diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index 51e0852..a818b67 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -27,6 +27,7 @@
     show
         ClassBuilder,
         Declaration,
+        FieldBuilder,
         ModifierBuilder,
         NameIterator,
         PrefixBuilder,
@@ -237,6 +238,8 @@
   void recordAccess(int charOffset, int length, Uri fileUri) {}
 
   void buildOutlineExpressions() {}
+
+  List<FieldBuilder> takeImplicitlyTypedFields() => null;
 }
 
 class LibraryLocalDeclarationIterator implements Iterator<Declaration> {
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
index 0b99bf5..e714210 100644
--- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -4,6 +4,8 @@
 
 library fasta.member_builder;
 
+import '../problems.dart' show unsupported;
+
 import 'builder.dart'
     show ClassBuilder, Declaration, LibraryBuilder, ModifierBuilder;
 
@@ -41,4 +43,10 @@
 
   @override
   String get fullNameForErrors => name;
+
+  void inferType() => unsupported("inferType", charOffset, fileUri);
+
+  void inferCopiedType(covariant Object other) {
+    unsupported("inferType", charOffset, fileUri);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index de913de..aaa62c8 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -590,6 +590,36 @@
     tip: r"""Try specifying the file explicitly with the --packages option.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateCantInferReturnTypeDueToInconsistentOverrides =
+    const Template<Message Function(String name)>(
+        messageTemplate:
+            r"""Can't infer a return type for '#name' as some of the inherited members have different types.""",
+        tipTemplate: r"""Try adding an explicit type.""",
+        withArguments:
+            _withArgumentsCantInferReturnTypeDueToInconsistentOverrides);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+    codeCantInferReturnTypeDueToInconsistentOverrides =
+    const Code<Message Function(String name)>(
+        "CantInferReturnTypeDueToInconsistentOverrides",
+        templateCantInferReturnTypeDueToInconsistentOverrides,
+        analyzerCodes: <String>["INVALID_METHOD_OVERRIDE"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCantInferReturnTypeDueToInconsistentOverrides(
+    String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeCantInferReturnTypeDueToInconsistentOverrides,
+      message:
+          """Can't infer a return type for '${name}' as some of the inherited members have different types.""",
+      tip: """Try adding an explicit type.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
         String
@@ -786,6 +816,38 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
+        String name,
+        String
+            name2)> templateCombinedMemberSignatureFailed = const Template<
+        Message Function(String name, String name2)>(
+    messageTemplate:
+        r"""Class '#name' inherits multiple members named '#name2' with incompatible signatures.""",
+    tipTemplate: r"""Try adding a declaration of '#name2' to '#name'.""",
+    withArguments: _withArgumentsCombinedMemberSignatureFailed);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, String name2)>
+    codeCombinedMemberSignatureFailed =
+    const Code<Message Function(String name, String name2)>(
+        "CombinedMemberSignatureFailed", templateCombinedMemberSignatureFailed,
+        analyzerCodes: <String>["INCONSISTENT_INHERITANCE"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsCombinedMemberSignatureFailed(String name, String name2) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  if (name2.isEmpty) throw 'No name provided';
+  name2 = demangleMixinApplicationName(name2);
+  return new Message(codeCombinedMemberSignatureFailed,
+      message:
+          """Class '${name}' inherits multiple members named '${name2}' with incompatible signatures.""",
+      tip: """Try adding a declaration of '${name2}' to '${name}'.""",
+      arguments: {'name': name, 'name2': name2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
         String string,
         String
             string2)> templateConflictingModifiers = const Template<
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 2593336..697f844 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -8,14 +8,19 @@
     show
         Class,
         DartType,
+        Field,
+        FunctionNode,
         InterfaceType,
-        TypeParameter,
+        InvalidType,
         Library,
         Member,
         Name,
         Procedure,
         ProcedureKind,
-        Supertype;
+        Supertype,
+        TypeParameter,
+        TypeParameterType,
+        VariableDeclaration;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 
@@ -23,6 +28,8 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
+import '../dill/dill_member_builder.dart' show DillMemberBuilder;
+
 import '../loader.dart' show Loader;
 
 import '../messages.dart'
@@ -36,15 +43,23 @@
         messageInheritedMembersConflictCause2,
         messageStaticAndInstanceConflict,
         messageStaticAndInstanceConflictCause,
+        templateCantInferReturnTypeDueToInconsistentOverrides,
+        templateCantInferTypeDueToInconsistentOverrides,
+        templateCombinedMemberSignatureFailed,
         templateDuplicatedDeclaration,
         templateDuplicatedDeclarationCause,
+        templateDuplicatedDeclarationUse,
         templateMissingImplementationCause,
         templateMissingImplementationNotAbstract;
 
 import '../names.dart' show noSuchMethodName;
 
+import '../problems.dart' show unhandled;
+
 import '../scope.dart' show Scope;
 
+import '../source/source_loader.dart' show SourceLoader;
+
 import '../type_inference/standard_bounds.dart' show StandardBounds;
 
 import '../type_inference/type_constraint_gatherer.dart'
@@ -56,18 +71,35 @@
 
 import '../type_inference/type_schema_environment.dart' show TypeConstraint;
 
+import 'forwarding_node.dart' show ForwardingNode;
+
 import 'kernel_builder.dart'
     show
         Declaration,
+        FormalParameterBuilder,
+        ImplicitFieldType,
         KernelClassBuilder,
+        KernelFieldBuilder,
+        KernelLibraryBuilder,
         KernelNamedTypeBuilder,
+        KernelProcedureBuilder,
         KernelTypeBuilder,
+        KernelTypeVariableBuilder,
         LibraryBuilder,
+        MemberBuilder,
         TypeBuilder,
         TypeVariableBuilder;
 
 import 'types.dart' show Types;
 
+const DebugLogger debug =
+    const bool.fromEnvironment("debug.hierarchy") ? const DebugLogger() : null;
+
+class DebugLogger {
+  const DebugLogger();
+  void log(Object message) => print(message);
+}
+
 int compareDeclarations(Declaration a, Declaration b) {
   return ClassHierarchy.compareMembers(a.target, b.target);
 }
@@ -94,6 +126,7 @@
   if (b.isField) return !(a.isField || a.isGetter || a.isSetter);
   if (a.isSetter) return !(b.isGetter || b.isSetter);
   if (b.isSetter) return !(a.isGetter || a.isSetter);
+  if (a is InterfaceConflict || b is InterfaceConflict) return false;
   return true;
 }
 
@@ -101,6 +134,68 @@
   return declaration.isField && !(declaration.isFinal || declaration.isConst);
 }
 
+bool hasSameSignature(FunctionNode a, FunctionNode b) {
+  List<TypeParameter> aTypeParameters = a.typeParameters;
+  List<TypeParameter> bTypeParameters = b.typeParameters;
+  int typeParameterCount = aTypeParameters.length;
+  if (typeParameterCount != bTypeParameters.length) return false;
+  Substitution substitution;
+  if (typeParameterCount != 0) {
+    List<DartType> types = new List<DartType>(typeParameterCount);
+    for (int i = 0; i < typeParameterCount; i++) {
+      types[i] = new TypeParameterType(aTypeParameters[i]);
+    }
+    substitution = Substitution.fromPairs(bTypeParameters, types);
+    for (int i = 0; i < typeParameterCount; i++) {
+      DartType aBound = aTypeParameters[i].bound;
+      DartType bBound = substitution.substituteType(bTypeParameters[i].bound);
+      if (aBound != bBound) return false;
+    }
+  }
+
+  if (a.requiredParameterCount != b.requiredParameterCount) return false;
+  List<VariableDeclaration> aPositionalParameters = a.positionalParameters;
+  List<VariableDeclaration> bPositionalParameters = b.positionalParameters;
+  if (aPositionalParameters.length != bPositionalParameters.length) {
+    return false;
+  }
+  for (int i = 0; i < aPositionalParameters.length; i++) {
+    VariableDeclaration aParameter = aPositionalParameters[i];
+    VariableDeclaration bParameter = bPositionalParameters[i];
+    if (aParameter.isCovariant != bParameter.isCovariant) return false;
+    DartType aType = aParameter.type;
+    DartType bType = bParameter.type;
+    if (substitution != null) {
+      bType = substitution.substituteType(bType);
+    }
+    if (aType != bType) return false;
+  }
+
+  List<VariableDeclaration> aNamedParameters = a.namedParameters;
+  List<VariableDeclaration> bNamedParameters = b.namedParameters;
+  if (aNamedParameters.length != bNamedParameters.length) return false;
+  for (int i = 0; i < aNamedParameters.length; i++) {
+    VariableDeclaration aParameter = aNamedParameters[i];
+    VariableDeclaration bParameter = bNamedParameters[i];
+    if (aParameter.isCovariant != bParameter.isCovariant) return false;
+    if (aParameter.name != bParameter.name) return false;
+    DartType aType = aParameter.type;
+    DartType bType = bParameter.type;
+    if (substitution != null) {
+      bType = substitution.substituteType(bType);
+    }
+    if (aType != bType) return false;
+  }
+
+  DartType aReturnType = a.returnType;
+  DartType bReturnType = b.returnType;
+  if (substitution != null) {
+    bReturnType = substitution.substituteType(bReturnType);
+  }
+
+  return aReturnType == bReturnType;
+}
+
 class ClassHierarchyBuilder {
   final Map<Class, ClassHierarchyNode> nodes = <Class, ClassHierarchyNode>{};
 
@@ -118,6 +213,10 @@
 
   final Class nullKernelClass;
 
+  final List<DelayedOverrideCheck> overrideChecks = <DelayedOverrideCheck>[];
+
+  final List<DelayedMember> delayedMemberChecks = <DelayedMember>[];
+
   // TODO(ahe): Remove this.
   final CoreTypes coreTypes;
 
@@ -138,10 +237,8 @@
   }
 
   ClassHierarchyNode getNodeFromType(KernelTypeBuilder type) {
-    Declaration declaration = type.declaration;
-    return declaration is KernelClassBuilder
-        ? getNodeFromClass(declaration)
-        : null;
+    KernelClassBuilder cls = getClass(type);
+    return cls == null ? null : getNodeFromClass(cls);
   }
 
   ClassHierarchyNode getNodeFromKernelClass(Class cls) {
@@ -190,7 +287,9 @@
     }
     KernelNamedTypeBuilder supertype = asSupertypeOf(kernelClass, superclass);
     if (supertype == null) return null;
-    if (supertype.arguments == null) return superclass.rawType;
+    if (supertype.arguments == null && superclass.typeParameters.isEmpty) {
+      return superclass.rawType;
+    }
     return Substitution.fromInterfaceType(type)
         .substituteType(supertype.build(null));
   }
@@ -232,17 +331,54 @@
     return objectKernelClass.rawType;
   }
 
+  Member getInterfaceMemberKernel(Class cls, Name name, bool isSetter) {
+    return getNodeFromKernelClass(cls)
+        .getInterfaceMember(name, isSetter)
+        ?.target;
+  }
+
+  Member getDispatchTargetKernel(Class cls, Name name, bool isSetter) {
+    return getNodeFromKernelClass(cls)
+        .getDispatchTarget(name, isSetter)
+        ?.target;
+  }
+
+  Member getCombinedMemberSignatureKernel(Class cls, Name name, bool isSetter,
+      int charOffset, KernelLibraryBuilder library) {
+    Declaration declaration =
+        getNodeFromKernelClass(cls).getInterfaceMember(name, isSetter);
+    if (declaration?.isStatic ?? true) return null;
+    if (declaration.next != null) {
+      library?.addProblem(
+          templateDuplicatedDeclarationUse.withArguments(name.name),
+          charOffset,
+          name.name.length,
+          library.fileUri);
+      return null;
+    }
+    if (declaration is DelayedMember) {
+      return declaration.check(this);
+    } else {
+      return declaration.target;
+    }
+  }
+
   static ClassHierarchyBuilder build(
       KernelClassBuilder objectClass,
       List<KernelClassBuilder> classes,
-      Loader<Object> loader,
+      SourceLoader loader,
       CoreTypes coreTypes) {
     ClassHierarchyBuilder hierarchy =
         new ClassHierarchyBuilder(objectClass, loader, coreTypes);
     for (int i = 0; i < classes.length; i++) {
       KernelClassBuilder cls = classes[i];
-      hierarchy.nodes[cls.target] =
-          new ClassHierarchyNodeBuilder(hierarchy, cls).build();
+      if (!cls.isPatch) {
+        hierarchy.nodes[cls.target] =
+            new ClassHierarchyNodeBuilder(hierarchy, cls).build();
+      } else {
+        // TODO(ahe): Merge the injected members of patch into the hierarchy
+        // node of `cls.origin`.
+      }
     }
     return hierarchy;
   }
@@ -261,6 +397,8 @@
 
   KernelClassBuilder get objectClass => hierarchy.objectClass;
 
+  final Map<Class, Substitution> substitutions = <Class, Substitution>{};
+
   /// When merging `aList` and `bList`, [a] (from `aList`) and [b] (from
   /// `bList`) each have the same name.
   ///
@@ -271,44 +409,563 @@
   ///
   /// If [mergeKind] is `MergeKind.supertypes`, [a] should implement [b], and
   /// [b] is implicitly abstract.
-  Declaration handleMergeConflict(KernelClassBuilder cls, Declaration a,
-      Declaration b, MergeKind mergeKind) {
+  Declaration handleMergeConflict(
+      Declaration a, Declaration b, MergeKind mergeKind) {
+    debug?.log(
+        "handleMergeConflict: ${fullName(a)} ${fullName(b)} ${mergeKind}");
+    // TODO(ahe): Enable this optimization, but be careful about abstract
+    // methods overriding concrete methods.
+    // if (cls is DillClassBuilder) return a;
     if (a == b) return a;
     if (a.next != null || b.next != null) {
       // Don't check overrides involving duplicated members.
       return a;
     }
-    if (isInheritanceConflict(a, b)) {
-      reportInheritanceConflict(cls, a, b);
-    }
-    Declaration result = a;
-    if (mergeKind == MergeKind.accessors) {
-    } else if (mergeKind == MergeKind.interfaces) {
-      // TODO(ahe): Combine the signatures of a and b.  See the section named
-      // "Combined Member Signatures" in [Dart Programming Language
-      // Specification](
-      // ../../../../../../docs/language/dartLangSpec.tex#combinedMemberSignatures).
-    } else if (a.target.isAbstract) {
-      if (mergeKind == MergeKind.superclass && !b.target.isAbstract) {
-        // An abstract method doesn't override an implemention inherited from a
-        // superclass.
-        result = b;
-      } else {
-        (abstractMembers ??= <Declaration>[]).add(a);
-      }
-    }
+    Declaration result = checkInheritanceConflict(a, b);
+    if (result != null) return result;
+    result = a;
+    switch (mergeKind) {
+      case MergeKind.superclassMembers:
+      case MergeKind.superclassSetters:
+        // [a] is a method declared in [cls]. This means it defines the
+        // interface of this class regardless if its abstract.
+        debug?.log(
+            "superclass: checkValidOverride(${cls.fullNameForErrors}, ${fullName(a)}, ${fullName(b)})");
+        checkValidOverride(
+            a, AbstractMemberOverridingImplementation.selectAbstract(b));
 
-    if (mergeKind == MergeKind.superclass &&
-        result.fullNameForErrors == noSuchMethodName.name &&
-        result.parent != objectClass) {
-      hasNoSuchMethod = true;
+        if (isAbstract(a)) {
+          if (isAbstract(b)) {
+            recordAbstractMember(a);
+          } else {
+            if (!cls.isAbstract) {
+              // The interface of this class is [a]. But the implementation is
+              // [b]. So [b] must implement [a], unless [cls] is abstract.
+              checkValidOverride(b, a);
+            }
+            result = new AbstractMemberOverridingImplementation(
+                cls,
+                a,
+                AbstractMemberOverridingImplementation.selectConcrete(b),
+                mergeKind == MergeKind.superclassSetters,
+                cls.library.loader == hierarchy.loader);
+            hierarchy.delayedMemberChecks.add(result);
+          }
+        }
+
+        Member target = result.target;
+        if (target.enclosingClass != objectClass.cls &&
+            target.name == noSuchMethodName) {
+          hasNoSuchMethod = true;
+        }
+        break;
+
+      case MergeKind.membersWithSetters:
+      case MergeKind.settersWithMembers:
+        if (a.parent == cls && b.parent != cls) {
+          if (a is KernelFieldBuilder) {
+            if (a.isFinal && b.isSetter) {
+              hierarchy.overrideChecks.add(new DelayedOverrideCheck(cls, a, b));
+            } else {
+              if (!inferFieldTypes(a, b)) {
+                hierarchy.overrideChecks
+                    .add(new DelayedOverrideCheck(cls, a, b));
+              }
+            }
+          } else if (a is KernelProcedureBuilder) {
+            if (!inferMethodTypes(a, b)) {
+              hierarchy.overrideChecks.add(new DelayedOverrideCheck(cls, a, b));
+            }
+          }
+        }
+        break;
+
+      case MergeKind.interfacesMembers:
+        result = InterfaceConflict.combined(
+            cls, a, b, false, cls.library.loader == hierarchy.loader);
+        break;
+
+      case MergeKind.interfacesSetters:
+        result = InterfaceConflict.combined(
+            cls, a, b, true, cls.library.loader == hierarchy.loader);
+        break;
+
+      case MergeKind.supertypesMembers:
+      case MergeKind.supertypesSetters:
+        // [b] is inherited from an interface so it is implicitly abstract.
+
+        a = AbstractMemberOverridingImplementation.selectAbstract(a);
+        b = AbstractMemberOverridingImplementation.selectAbstract(b);
+
+        // If [a] is declared in this class, it defines the interface.
+        if (a.parent == cls) {
+          debug?.log(
+              "supertypes: checkValidOverride(${cls.fullNameForErrors}, ${fullName(a)}, ${fullName(b)})");
+          checkValidOverride(a, b);
+        } else {
+          if (isAbstract(a)) {
+            result = InterfaceConflict.combined(
+                cls,
+                a,
+                b,
+                mergeKind == MergeKind.supertypesSetters,
+                cls.library.loader == hierarchy.loader);
+          } else {
+            result = InheritedImplementationInterfaceConflict.combined(
+                cls,
+                a,
+                b,
+                mergeKind == MergeKind.supertypesSetters,
+                cls.library.loader == hierarchy.loader);
+          }
+          debug?.log("supertypes: ${result}");
+          if (result is DelayedMember) {
+            hierarchy.delayedMemberChecks.add(result);
+          }
+        }
+        break;
     }
 
     return result;
   }
 
-  void reportInheritanceConflict(
-      KernelClassBuilder cls, Declaration a, Declaration b) {
+  Declaration checkInheritanceConflict(Declaration a, Declaration b) {
+    if (a is DelayedMember) {
+      Declaration result;
+      for (int i = 0; i < a.declarations.length; i++) {
+        Declaration d = checkInheritanceConflict(a.declarations[i], b);
+        result ??= d;
+      }
+      return result;
+    }
+    if (b is DelayedMember) {
+      Declaration result;
+      for (int i = 0; i < b.declarations.length; i++) {
+        Declaration d = checkInheritanceConflict(a, b.declarations[i]);
+        result ??= d;
+      }
+      return result;
+    }
+    if (isInheritanceConflict(a, b)) {
+      reportInheritanceConflict(a, b);
+      return a;
+    }
+    return null;
+  }
+
+  bool inferMethodTypes(KernelProcedureBuilder a, Declaration b) {
+    debug?.log(
+        "Trying to infer types for ${fullName(a)} based on ${fullName(b)}");
+    if (b is DelayedMember) {
+      bool hasSameSignature = true;
+      List<Declaration> declarations = b.declarations;
+      for (int i = 0; i < declarations.length; i++) {
+        if (!inferMethodTypes(a, declarations[i])) {
+          hasSameSignature = false;
+        }
+      }
+      return hasSameSignature;
+    }
+    if (a.isGetter) {
+      return inferGetterType(a, b);
+    } else if (a.isSetter) {
+      return inferSetterType(a, b);
+    }
+    bool hadTypesInferred = a.hadTypesInferred;
+    KernelClassBuilder aCls = a.parent;
+    Substitution aSubstitution;
+    if (cls != aCls) {
+      assert(substitutions.containsKey(aCls.target),
+          "${cls.fullNameForErrors} ${aCls.fullNameForErrors}");
+      aSubstitution = substitutions[aCls.target];
+      debug?.log(
+          "${cls.fullNameForErrors} -> ${aCls.fullNameForErrors} $aSubstitution");
+    }
+    KernelClassBuilder bCls = b.parent;
+    Substitution bSubstitution;
+    if (cls != bCls) {
+      assert(substitutions.containsKey(bCls.target),
+          "${cls.fullNameForErrors} ${bCls.fullNameForErrors}");
+      bSubstitution = substitutions[bCls.target];
+      debug?.log(
+          "${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} $bSubstitution");
+    }
+    Procedure aProcedure = a.target;
+    if (b.target is! Procedure) {
+      debug?.log("Giving up 1");
+      return false;
+    }
+    Procedure bProcedure = b.target;
+    FunctionNode aFunction = aProcedure.function;
+    FunctionNode bFunction = bProcedure.function;
+
+    List<TypeParameter> aTypeParameters = aFunction.typeParameters;
+    List<TypeParameter> bTypeParameters = bFunction.typeParameters;
+    int typeParameterCount = aTypeParameters.length;
+    if (typeParameterCount != bTypeParameters.length) {
+      debug?.log("Giving up 2");
+      return false;
+    }
+    Substitution substitution;
+    if (typeParameterCount != 0) {
+      List<DartType> types = new List<DartType>(typeParameterCount);
+      for (int i = 0; i < typeParameterCount; i++) {
+        types[i] = new TypeParameterType(aTypeParameters[i]);
+      }
+      substitution = Substitution.fromPairs(bTypeParameters, types);
+      for (int i = 0; i < typeParameterCount; i++) {
+        DartType aBound = aTypeParameters[i].bound;
+        DartType bBound = substitution.substituteType(bTypeParameters[i].bound);
+        if (aBound != bBound) {
+          debug?.log("Giving up 3");
+          return false;
+        }
+      }
+    }
+
+    DartType aReturnType = aFunction.returnType;
+    if (aSubstitution != null) {
+      aReturnType = aSubstitution.substituteType(aReturnType);
+    }
+    DartType bReturnType = bFunction.returnType;
+    if (bSubstitution != null) {
+      bReturnType = bSubstitution.substituteType(bReturnType);
+    }
+    if (substitution != null) {
+      bReturnType = substitution.substituteType(bReturnType);
+    }
+    bool result = true;
+    if (aFunction.requiredParameterCount > bFunction.requiredParameterCount) {
+      debug?.log("Giving up 4");
+      return false;
+    }
+    List<VariableDeclaration> aPositional = aFunction.positionalParameters;
+    List<VariableDeclaration> bPositional = bFunction.positionalParameters;
+    if (aPositional.length < bPositional.length) {
+      debug?.log("Giving up 5");
+      return false;
+    }
+
+    if (aReturnType != bReturnType) {
+      if (a.parent == cls && a.returnType == null) {
+        result =
+            inferReturnType(cls, a, bReturnType, hadTypesInferred, hierarchy);
+      } else {
+        debug?.log("Giving up 6");
+        result = false;
+      }
+    }
+
+    for (int i = 0; i < bPositional.length; i++) {
+      VariableDeclaration aParameter = aPositional[i];
+      VariableDeclaration bParameter = bPositional[i];
+      copyParameterCovariance(a.parent, aParameter, bParameter);
+      DartType aType = aParameter.type;
+      if (aSubstitution != null) {
+        aType = aSubstitution.substituteType(aType);
+      }
+      DartType bType = bParameter.type;
+      if (bSubstitution != null) {
+        bType = bSubstitution.substituteType(bType);
+      }
+      if (substitution != null) {
+        bType = substitution.substituteType(bType);
+      }
+      if (aType != bType) {
+        if (a.parent == cls && a.formals[i].type == null) {
+          result = inferParameterType(
+              cls, a, a.formals[i], bType, hadTypesInferred, hierarchy);
+        } else {
+          debug?.log("Giving up 8");
+          result = false;
+        }
+      }
+    }
+
+    List<VariableDeclaration> aNamed = aFunction.namedParameters;
+    List<VariableDeclaration> bNamed = bFunction.namedParameters;
+    named:
+    if (aNamed.isNotEmpty || bNamed.isNotEmpty) {
+      if (aPositional.length != bPositional.length) {
+        debug?.log("Giving up 9");
+        result = false;
+        break named;
+      }
+      if (aFunction.requiredParameterCount !=
+          bFunction.requiredParameterCount) {
+        debug?.log("Giving up 10");
+        result = false;
+        break named;
+      }
+
+      aNamed = aNamed.toList()..sort(compareNamedParameters);
+      bNamed = bNamed.toList()..sort(compareNamedParameters);
+      int aCount = 0;
+      for (int bCount = 0; bCount < bNamed.length; bCount++) {
+        String name = bNamed[bCount].name;
+        for (; aCount < aNamed.length; aCount++) {
+          if (aNamed[aCount].name == name) break;
+        }
+        if (aCount == aNamed.length) {
+          debug?.log("Giving up 11");
+          result = false;
+          break named;
+        }
+        VariableDeclaration aParameter = aNamed[aCount];
+        VariableDeclaration bParameter = bNamed[bCount];
+        copyParameterCovariance(a.parent, aParameter, bParameter);
+        DartType aType = aParameter.type;
+        DartType bType = bParameter.type;
+        if (substitution != null) {
+          bType = substitution.substituteType(bType);
+        }
+        if (aType != bType) {
+          FormalParameterBuilder<KernelTypeBuilder> parameter =
+              a.formals[aPositional.length + aCount];
+          if (a.parent == cls && parameter.type == null) {
+            result = inferParameterType(
+                cls, a, parameter, bType, hadTypesInferred, hierarchy);
+          } else {
+            debug?.log("Giving up 12");
+            result = false;
+          }
+        }
+      }
+    }
+    debug?.log("Inferring types for ${fullName(a)} based on ${fullName(b)} " +
+        (result ? "succeeded." : "failed."));
+    return result;
+  }
+
+  bool inferGetterType(KernelProcedureBuilder a, Declaration b) {
+    debug?.log(
+        "Inferring getter types for ${fullName(a)} based on ${fullName(b)}");
+    Member bTarget = b.target;
+    DartType bType;
+    if (bTarget is Field) {
+      bType = bTarget.type;
+    } else if (bTarget is Procedure) {
+      if (b.isSetter) {
+        VariableDeclaration bParameter =
+            bTarget.function.positionalParameters.single;
+        bType = bParameter.type;
+        if (!hasExplictlyTypedFormalParameter(b, 0)) {
+          debug?.log("Giving up (type may be inferred)");
+          return false;
+        }
+      } else if (b.isGetter) {
+        bType = bTarget.function.returnType;
+        if (!hasExplicitReturnType(b)) {
+          debug?.log("Giving up (return type may be inferred)");
+          return false;
+        }
+      } else {
+        debug?.log("Giving up (not accessor: ${bTarget.kind})");
+        return false;
+      }
+    } else {
+      debug?.log("Giving up (not field/procedure: ${bTarget.runtimeType})");
+      return false;
+    }
+    return a.target.function.returnType == bType;
+  }
+
+  bool inferSetterType(KernelProcedureBuilder a, Declaration b) {
+    debug?.log(
+        "Inferring getter types for ${fullName(a)} based on ${fullName(b)}");
+    Member bTarget = b.target;
+    Procedure aProcedure = a.target;
+    VariableDeclaration aParameter =
+        aProcedure.function.positionalParameters.single;
+    DartType bType;
+    if (bTarget is Field) {
+      bType = bTarget.type;
+      copyParameterCovarianceFromField(a.parent, aParameter, bTarget);
+    }
+    if (bTarget is Procedure) {
+      if (b.isSetter) {
+        VariableDeclaration bParameter =
+            bTarget.function.positionalParameters.single;
+        bType = bParameter.type;
+        copyParameterCovariance(a.parent, aParameter, bParameter);
+        if (!hasExplictlyTypedFormalParameter(b, 0)) {
+          debug?.log("Giving up (type may be inferred)");
+          return false;
+        }
+      } else if (b.isGetter) {
+        bType = bTarget.function.returnType;
+        if (!hasExplicitReturnType(b)) {
+          debug?.log("Giving up (return type may be inferred)");
+          return false;
+        }
+      } else {
+        debug?.log("Giving up (not accessor: ${bTarget.kind})");
+        return false;
+      }
+    } else {
+      debug?.log("Giving up (not field/procedure: ${bTarget.runtimeType})");
+      return false;
+    }
+    return aParameter.type == bType;
+  }
+
+  void checkValidOverride(Declaration a, Declaration b) {
+    debug?.log(
+        "checkValidOverride(${fullName(a)}, ${fullName(b)}) ${a.runtimeType}");
+    if (a is KernelProcedureBuilder) {
+      if (inferMethodTypes(a, b)) return;
+    } else if (a.isField) {
+      if (inferFieldTypes(a, b)) return;
+    }
+    Member aTarget = a.target;
+    Member bTarget = b.target;
+    if (aTarget is Procedure && !aTarget.isAccessor && bTarget is Procedure) {
+      if (hasSameSignature(aTarget.function, bTarget.function)) return;
+    }
+
+    if (b is DelayedMember) {
+      for (int i = 0; i < b.declarations.length; i++) {
+        hierarchy.overrideChecks
+            .add(new DelayedOverrideCheck(cls, a, b.declarations[i]));
+      }
+    } else {
+      hierarchy.overrideChecks.add(new DelayedOverrideCheck(cls, a, b));
+    }
+  }
+
+  bool inferFieldTypes(MemberBuilder a, Declaration b) {
+    debug?.log(
+        "Trying to infer field types for ${fullName(a)} based on ${fullName(b)}");
+    if (b is DelayedMember) {
+      bool hasSameSignature = true;
+      List<Declaration> declarations = b.declarations;
+      for (int i = 0; i < declarations.length; i++) {
+        if (!inferFieldTypes(a, declarations[i])) {
+          hasSameSignature = false;
+        }
+      }
+      return hasSameSignature;
+    }
+    Member bTarget = b.target;
+    DartType inheritedType;
+    if (bTarget is Procedure) {
+      if (bTarget.isSetter) {
+        VariableDeclaration parameter =
+            bTarget.function.positionalParameters.single;
+        // inheritedType = parameter.type;
+        copyFieldCovarianceFromParameter(a.parent, a.target, parameter);
+        if (!hasExplictlyTypedFormalParameter(b, 0)) {
+          debug?.log("Giving up (type may be inferred)");
+          return false;
+        }
+      } else if (bTarget.isGetter) {
+        if (!hasExplicitReturnType(b)) return false;
+        inheritedType = bTarget.function.returnType;
+      }
+    } else if (bTarget is Field) {
+      copyFieldCovariance(a.parent, a.target, bTarget);
+      inheritedType = bTarget.type;
+    }
+    if (inheritedType == null) {
+      debug?.log("Giving up (inheritedType == null)\n${StackTrace.current}");
+      return false;
+    }
+    KernelClassBuilder aCls = a.parent;
+    Substitution aSubstitution;
+    if (cls != aCls) {
+      assert(substitutions.containsKey(aCls.target),
+          "${cls.fullNameForErrors} ${aCls.fullNameForErrors}");
+      aSubstitution = substitutions[aCls.target];
+      debug?.log(
+          "${cls.fullNameForErrors} -> ${aCls.fullNameForErrors} $aSubstitution");
+    }
+    KernelClassBuilder bCls = b.parent;
+    Substitution bSubstitution;
+    if (cls != bCls) {
+      assert(substitutions.containsKey(bCls.target),
+          "${cls.fullNameForErrors} ${bCls.fullNameForErrors}");
+      bSubstitution = substitutions[bCls.target];
+      debug?.log(
+          "${cls.fullNameForErrors} -> ${bCls.fullNameForErrors} $bSubstitution");
+    }
+    if (bSubstitution != null) {
+      inheritedType = bSubstitution.substituteType(inheritedType);
+    }
+
+    DartType declaredType = a.target.type;
+    if (aSubstitution != null) {
+      declaredType = aSubstitution.substituteType(declaredType);
+    }
+    if (declaredType == inheritedType) return true;
+
+    bool result = false;
+    if (a is KernelFieldBuilder) {
+      if (a.parent == cls && a.type == null) {
+        if (a.hadTypesInferred) {
+          reportCantInferFieldType(cls, a);
+          inheritedType = const InvalidType();
+        } else {
+          result = true;
+          a.hadTypesInferred = true;
+        }
+        if (inheritedType is ImplicitFieldType) {
+          KernelLibraryBuilder library = cls.library;
+          (library.implicitlyTypedFields ??= <KernelFieldBuilder>[]).add(a);
+        }
+        a.target.type = inheritedType;
+      }
+    }
+    return result;
+  }
+
+  void copyParameterCovariance(Declaration parent,
+      VariableDeclaration aParameter, VariableDeclaration bParameter) {
+    if (parent == cls) {
+      if (bParameter.isCovariant) {
+        aParameter.isCovariant = true;
+      }
+      if (bParameter.isGenericCovariantImpl) {
+        aParameter.isGenericCovariantImpl = true;
+      }
+    }
+  }
+
+  void copyParameterCovarianceFromField(
+      Declaration parent, VariableDeclaration aParameter, Field bField) {
+    if (parent == cls) {
+      if (bField.isCovariant) {
+        aParameter.isCovariant = true;
+      }
+      if (bField.isGenericCovariantImpl) {
+        aParameter.isGenericCovariantImpl = true;
+      }
+    }
+  }
+
+  void copyFieldCovariance(Declaration parent, Field aField, Field bField) {
+    if (parent == cls) {
+      if (bField.isCovariant) {
+        aField.isCovariant = true;
+      }
+      if (bField.isGenericCovariantImpl) {
+        aField.isGenericCovariantImpl = true;
+      }
+    }
+  }
+
+  void copyFieldCovarianceFromParameter(
+      Declaration parent, Field aField, VariableDeclaration bParameter) {
+    if (parent == cls) {
+      if (bParameter.isCovariant) {
+        aField.isCovariant = true;
+      }
+      if (bParameter.isGenericCovariantImpl) {
+        aField.isGenericCovariantImpl = true;
+      }
+    }
+  }
+
+  void reportInheritanceConflict(Declaration a, Declaration b) {
     String name = a.fullNameForErrors;
     if (a.parent != b.parent) {
       if (a.parent == cls) {
@@ -374,8 +1031,17 @@
   /// If [mergeKind] is `MergeKind.supertypes`, [member] isn't
   /// implementing/overriding anything.
   void handleOnlyA(Declaration member, MergeKind mergeKind) {
-    if (mergeKind == MergeKind.superclass && member.target.isAbstract) {
-      (abstractMembers ??= <Declaration>[]).add(member);
+    if (mergeKind == MergeKind.interfacesMembers ||
+        mergeKind == MergeKind.interfacesSetters) {
+      return;
+    }
+    // TODO(ahe): Enable this optimization:
+    // if (cls is DillClassBuilder) return;
+    // assert(mergeKind == MergeKind.interfaces || member is! InterfaceConflict);
+    if ((mergeKind == MergeKind.superclassMembers ||
+            mergeKind == MergeKind.superclassSetters) &&
+        isAbstract(member)) {
+      recordAbstractMember(member);
     }
   }
 
@@ -388,30 +1054,49 @@
   ///
   /// If [mergeKind] is `MergeKind.supertypes`, [member] is implicitly
   /// abstract, and not implemented.
-  void handleOnlyB(
-      KernelClassBuilder cls, Declaration member, MergeKind mergeKind) {
+  Declaration handleOnlyB(Declaration member, MergeKind mergeKind) {
+    if (mergeKind == MergeKind.interfacesMembers ||
+        mergeKind == MergeKind.interfacesSetters) {
+      return member;
+    }
+    // TODO(ahe): Enable this optimization:
+    // if (cls is DillClassBuilder) return member;
     Member target = member.target;
-    if (mergeKind == MergeKind.supertypes ||
-        (mergeKind == MergeKind.superclass && target.isAbstract)) {
+    if ((mergeKind == MergeKind.supertypesMembers ||
+            mergeKind == MergeKind.supertypesSetters) ||
+        ((mergeKind == MergeKind.superclassMembers ||
+                mergeKind == MergeKind.superclassSetters) &&
+            target.isAbstract)) {
       if (isNameVisibleIn(target.name, cls.library)) {
-        (abstractMembers ??= <Declaration>[]).add(member);
+        recordAbstractMember(member);
       }
     }
-    if (member.parent != objectClass &&
-        target.name == noSuchMethodName &&
-        !target.isAbstract) {
+    if (mergeKind == MergeKind.superclassMembers &&
+        target.enclosingClass != objectClass.cls &&
+        target.name == noSuchMethodName) {
       hasNoSuchMethod = true;
     }
+    if (mergeKind != MergeKind.membersWithSetters &&
+        mergeKind != MergeKind.settersWithMembers &&
+        member is DelayedMember) {
+      hierarchy.delayedMemberChecks.add(member.withParent(cls));
+    }
+    return member;
+  }
+
+  void recordAbstractMember(Declaration member) {
+    abstractMembers ??= <Declaration>[];
+    if (member is DelayedMember) {
+      abstractMembers.addAll(member.declarations);
+    } else {
+      abstractMembers.add(member);
+    }
   }
 
   ClassHierarchyNode build() {
-    if (cls.isPatch) {
-      // TODO(ahe): What about patch classes. Have we injected patched members
-      // into the class-builder's scope?
-      return null;
-    }
+    assert(!cls.isPatch);
     ClassHierarchyNode supernode;
-    if (objectClass != cls) {
+    if (objectClass != cls.origin) {
       supernode = hierarchy.getNodeFromType(cls.supertype);
       if (supernode == null) {
         supernode = hierarchy.getNodeFromClass(objectClass);
@@ -423,8 +1108,10 @@
     if (cls.isMixinApplication) {
       Declaration mixin = cls.mixedInType.declaration;
       inferMixinApplication();
+      // recordSupertype(cls.mixedInType);
       while (mixin.isNamedMixinApplication) {
         KernelClassBuilder named = mixin;
+        // recordSupertype(named.mixedInType);
         mixin = named.mixedInType.declaration;
       }
       if (mixin is KernelClassBuilder) {
@@ -443,7 +1130,7 @@
           ..sort(compareDeclarations);
 
     // Add implied setters from fields in [localMembers].
-    localSetters = mergeAccessors(cls, localMembers, localSetters);
+    localSetters = mergeAccessors(localMembers, localSetters);
 
     /// Members (excluding setters) declared in [cls] or its superclasses. This
     /// includes static methods of [cls], but not its superclasses.
@@ -482,23 +1169,9 @@
           new List<KernelTypeBuilder>(supernode.superclasses.length + 1);
       superclasses.setRange(0, superclasses.length - 1,
           substSupertypes(cls.supertype, supernode.superclasses));
-      superclasses[superclasses.length - 1] = cls.supertype;
+      superclasses[superclasses.length - 1] = recordSupertype(cls.supertype);
 
-      classMembers = merge(
-          cls, localMembers, supernode.classMembers, MergeKind.superclass);
-      classSetters = merge(
-          cls, localSetters, supernode.classSetters, MergeKind.superclass);
-
-      // Check if local members conflict with inherited setters. This check has
-      // already been performed in the superclass, so we only need to check the
-      // local members.
-      merge(cls, localMembers, classSetters, MergeKind.accessors);
-
-      // Check if local setters conflict with inherited members. As above, we
-      // only need to check the local setters.
-      merge(cls, localSetters, classMembers, MergeKind.accessors);
-
-      List<KernelTypeBuilder> directInterfaces = cls.interfaces;
+      List<KernelTypeBuilder> directInterfaces = ignoreFunction(cls.interfaces);
       if (cls.isMixinApplication) {
         if (directInterfaces == null) {
           directInterfaces = <KernelTypeBuilder>[cls.mixedInType];
@@ -508,15 +1181,29 @@
         }
       }
       if (directInterfaces != null) {
-        MergeResult result = mergeInterfaces(cls, supernode, directInterfaces);
+        for (int i = 0; i < directInterfaces.length; i++) {
+          recordSupertype(directInterfaces[i]);
+        }
+      }
+      List<KernelTypeBuilder> superclassInterfaces = supernode.interfaces;
+      if (superclassInterfaces != null) {
+        superclassInterfaces =
+            substSupertypes(cls.supertype, superclassInterfaces);
+      }
+
+      classMembers = merge(
+          localMembers, supernode.classMembers, MergeKind.superclassMembers);
+      classSetters = merge(
+          localSetters, supernode.classSetters, MergeKind.superclassSetters);
+
+      if (directInterfaces != null) {
+        MergeResult result = mergeInterfaces(supernode, directInterfaces);
         interfaceMembers = result.mergedMembers;
         interfaceSetters = result.mergedSetters;
         interfaces = <KernelTypeBuilder>[];
-        if (supernode.interfaces != null) {
-          List<KernelTypeBuilder> types =
-              substSupertypes(cls.supertype, supernode.interfaces);
-          for (int i = 0; i < types.length; i++) {
-            addInterface(interfaces, superclasses, types[i]);
+        if (superclassInterfaces != null) {
+          for (int i = 0; i < superclassInterfaces.length; i++) {
+            addInterface(interfaces, superclasses, superclassInterfaces[i]);
           }
         }
         for (int i = 0; i < directInterfaces.length; i++) {
@@ -546,30 +1233,41 @@
       } else {
         interfaceMembers = supernode.interfaceMembers;
         interfaceSetters = supernode.interfaceSetters;
-        interfaces = substSupertypes(cls.supertype, supernode.interfaces);
+        interfaces = superclassInterfaces;
       }
+
+      // Check if local members conflict with inherited setters. This check has
+      // already been performed in the superclass, so we only need to check the
+      // local members. These checks have to occur late to enable inferring
+      // types between setters and getters, or from a setter to a final field.
+      merge(localMembers, classSetters, MergeKind.membersWithSetters);
+
+      // Check if local setters conflict with inherited members. As above, we
+      // only need to check the local setters.
+      merge(localSetters, classMembers, MergeKind.settersWithMembers);
+
       if (interfaceMembers != null) {
         interfaceMembers =
-            merge(cls, classMembers, interfaceMembers, MergeKind.supertypes);
+            merge(classMembers, interfaceMembers, MergeKind.supertypesMembers);
 
         // Check if class setters conflict with members inherited from
         // interfaces.
-        merge(cls, classSetters, interfaceMembers, MergeKind.accessors);
+        merge(classSetters, interfaceMembers, MergeKind.settersWithMembers);
       }
       if (interfaceSetters != null) {
         interfaceSetters =
-            merge(cls, classSetters, interfaceSetters, MergeKind.supertypes);
+            merge(classSetters, interfaceSetters, MergeKind.supertypesSetters);
 
         // Check if class members conflict with setters inherited from
         // interfaces.
-        merge(cls, classMembers, interfaceSetters, MergeKind.accessors);
+        merge(classMembers, interfaceSetters, MergeKind.membersWithSetters);
       }
     }
     if (abstractMembers != null && !cls.isAbstract) {
       if (!hasNoSuchMethod) {
-        reportMissingMembers(cls);
+        reportMissingMembers();
       } else {
-        installNsmHandlers(cls);
+        installNsmHandlers();
       }
     }
     return new ClassHierarchyNode(
@@ -584,6 +1282,41 @@
     );
   }
 
+  KernelTypeBuilder recordSupertype(KernelTypeBuilder supertype) {
+    if (supertype is KernelNamedTypeBuilder) {
+      debug?.log(
+          "In ${this.cls.fullNameForErrors} recordSupertype(${supertype.fullNameForErrors})");
+      Declaration declaration = supertype.declaration;
+      if (declaration is! KernelClassBuilder) return supertype;
+      KernelClassBuilder cls = declaration;
+      if (cls.isMixinApplication) {
+        recordSupertype(cls.mixedInType);
+      }
+      List<TypeVariableBuilder<TypeBuilder, Object>> typeVariables =
+          cls.typeVariables;
+      if (typeVariables == null) {
+        substitutions[cls.target] = Substitution.empty;
+        assert(cls.target.typeParameters.isEmpty);
+      } else {
+        List<KernelTypeBuilder> arguments =
+            supertype.arguments ?? computeDefaultTypeArguments(supertype);
+        if (arguments.length != typeVariables.length) {
+          arguments = computeDefaultTypeArguments(supertype);
+        }
+        List<DartType> kernelArguments = new List<DartType>(arguments.length);
+        List<TypeParameter> kernelParameters =
+            new List<TypeParameter>(arguments.length);
+        for (int i = 0; i < arguments.length; i++) {
+          kernelParameters[i] = typeVariables[i].target;
+          kernelArguments[i] = arguments[i].build(this.cls.parent);
+        }
+        substitutions[cls.target] =
+            Substitution.fromPairs(kernelParameters, kernelArguments);
+      }
+    }
+    return supertype;
+  }
+
   List<KernelTypeBuilder> substSupertypes(
       KernelNamedTypeBuilder supertype, List<KernelTypeBuilder> supertypes) {
     Declaration declaration = supertype.declaration;
@@ -591,7 +1324,13 @@
     KernelClassBuilder cls = declaration;
     List<TypeVariableBuilder<TypeBuilder, Object>> typeVariables =
         cls.typeVariables;
-    if (typeVariables == null) return supertypes;
+    if (typeVariables == null) {
+      debug?.log("In ${this.cls.fullNameForErrors} $supertypes aren't substed");
+      for (int i = 0; i < supertypes.length; i++) {
+        recordSupertype(supertypes[i]);
+      }
+      return supertypes;
+    }
     Map<TypeVariableBuilder<TypeBuilder, Object>, TypeBuilder> substitution =
         <TypeVariableBuilder<TypeBuilder, Object>, TypeBuilder>{};
     List<KernelTypeBuilder> arguments =
@@ -602,10 +1341,14 @@
     List<KernelTypeBuilder> result;
     for (int i = 0; i < supertypes.length; i++) {
       KernelTypeBuilder supertype = supertypes[i];
-      KernelTypeBuilder substed = supertype.subst(substitution);
+      KernelTypeBuilder substed =
+          recordSupertype(supertype.subst(substitution));
       if (supertype != substed) {
+        debug?.log("In ${this.cls.fullNameForErrors} $supertype -> $substed");
         result ??= supertypes.toList();
         result[i] = substed;
+      } else {
+        debug?.log("In ${this.cls.fullNameForErrors} $supertype isn't substed");
       }
     }
     return result ?? supertypes;
@@ -616,7 +1359,9 @@
     List<KernelTypeBuilder> result =
         new List<KernelTypeBuilder>(cls.typeVariables.length);
     for (int i = 0; i < result.length; ++i) {
-      result[i] = cls.typeVariables[i].defaultType;
+      KernelTypeVariableBuilder tv = cls.typeVariables[i];
+      result[i] = tv.defaultType ??
+          cls.library.loader.computeTypeBuilder(tv.target.defaultType);
     }
     return result;
   }
@@ -644,8 +1389,10 @@
     return null;
   }
 
-  MergeResult mergeInterfaces(KernelClassBuilder cls,
+  MergeResult mergeInterfaces(
       ClassHierarchyNode supernode, List<KernelTypeBuilder> interfaces) {
+    debug?.log(
+        "mergeInterfaces($cls (${this.cls}) ${supernode.interfaces} ${interfaces}");
     List<List<Declaration>> memberLists =
         new List<List<Declaration>>(interfaces.length + 1);
     List<List<Declaration>> setterLists =
@@ -665,12 +1412,12 @@
             interfaceNode.interfaceSetters ?? interfaceNode.classSetters;
       }
     }
-    return new MergeResult(
-        mergeLists(cls, memberLists), mergeLists(cls, setterLists));
+    return new MergeResult(mergeLists(memberLists, MergeKind.interfacesMembers),
+        mergeLists(setterLists, MergeKind.interfacesSetters));
   }
 
   List<Declaration> mergeLists(
-      KernelClassBuilder cls, List<List<Declaration>> input) {
+      List<List<Declaration>> input, MergeKind mergeKind) {
     // This is a k-way merge sort (where k is `input.length + 1`). We merge the
     // lists pairwise, which reduces the number of lists to merge by half on
     // each iteration. Consequently, we perform O(log k) merges.
@@ -684,7 +1431,7 @@
         } else if (second == null) {
           output.add(first);
         } else {
-          output.add(merge(cls, first, second, MergeKind.interfaces));
+          output.add(merge(first, second, mergeKind));
         }
       }
       if (input.length.isOdd) {
@@ -698,7 +1445,7 @@
   /// Merge [and check] accessors. This entails copying mutable fields to
   /// setters to simulate implied setters, and checking that setters don't
   /// override regular methods.
-  List<Declaration> mergeAccessors(KernelClassBuilder cls,
+  List<Declaration> mergeAccessors(
       List<Declaration> members, List<Declaration> setters) {
     final List<Declaration> mergedSetters = new List<Declaration>.filled(
         members.length + setters.length, null,
@@ -743,7 +1490,7 @@
     }
   }
 
-  void reportMissingMembers(KernelClassBuilder cls) {
+  void reportMissingMembers() {
     Map<String, LocatedMessage> contextMap = <String, LocatedMessage>{};
     for (int i = 0; i < abstractMembers.length; i++) {
       Declaration declaration = abstractMembers[i];
@@ -773,12 +1520,12 @@
         context: context);
   }
 
-  void installNsmHandlers(KernelClassBuilder cls) {
+  void installNsmHandlers() {
     // TOOD(ahe): Implement this.
   }
 
-  List<Declaration> merge(KernelClassBuilder cls, List<Declaration> aList,
-      List<Declaration> bList, MergeKind mergeKind) {
+  List<Declaration> merge(
+      List<Declaration> aList, List<Declaration> bList, MergeKind mergeKind) {
     final List<Declaration> result = new List<Declaration>.filled(
         aList.length + bList.length, null,
         growable: true);
@@ -788,7 +1535,9 @@
     while (i < aList.length && j < bList.length) {
       final Declaration a = aList[i];
       final Declaration b = bList[j];
-      if (mergeKind == MergeKind.interfaces && a.isStatic) {
+      if ((mergeKind == MergeKind.interfacesMembers ||
+              mergeKind == MergeKind.interfacesSetters) &&
+          a.isStatic) {
         i++;
         continue;
       }
@@ -798,7 +1547,7 @@
       }
       final int compare = compareDeclarations(a, b);
       if (compare == 0) {
-        result[storeIndex++] = handleMergeConflict(cls, a, b, mergeKind);
+        result[storeIndex++] = handleMergeConflict(a, b, mergeKind);
         i++;
         j++;
       } else if (compare < 0) {
@@ -806,14 +1555,15 @@
         result[storeIndex++] = a;
         i++;
       } else {
-        handleOnlyB(cls, b, mergeKind);
-        result[storeIndex++] = b;
+        result[storeIndex++] = handleOnlyB(b, mergeKind);
         j++;
       }
     }
     while (i < aList.length) {
       final Declaration a = aList[i];
-      if (mergeKind != MergeKind.interfaces || !a.isStatic) {
+      if (!(mergeKind == MergeKind.interfacesMembers ||
+              mergeKind == MergeKind.interfacesSetters) ||
+          !a.isStatic) {
         handleOnlyA(a, mergeKind);
         result[storeIndex++] = a;
       }
@@ -822,8 +1572,7 @@
     while (j < bList.length) {
       final Declaration b = bList[j];
       if (!b.isStatic) {
-        handleOnlyB(cls, b, mergeKind);
-        result[storeIndex++] = b;
+        result[storeIndex++] = handleOnlyB(b, mergeKind);
       }
       j++;
     }
@@ -853,6 +1602,25 @@
     KernelNamedTypeBuilder mixedInType = cls.mixedInType;
     mixedInType.arguments = inferredArguments;
   }
+
+  /// The class Function from dart:core is supposed to be ignored when used as
+  /// an interface.
+  List<KernelTypeBuilder> ignoreFunction(List<KernelTypeBuilder> interfaces) {
+    if (interfaces == null) return null;
+    for (int i = 0; i < interfaces.length; i++) {
+      KernelClassBuilder cls = getClass(interfaces[i]);
+      if (cls != null && cls.target == hierarchy.functionKernelClass) {
+        if (interfaces.length == 1) {
+          return null;
+        } else {
+          interfaces = interfaces.toList();
+          interfaces.removeAt(i);
+          return ignoreFunction(interfaces);
+        }
+      }
+    }
+    return interfaces;
+  }
 }
 
 class ClassHierarchyNode {
@@ -980,6 +1748,42 @@
     }
   }
 
+  Declaration getInterfaceMember(Name name, bool isSetter) {
+    return findMember(
+        name,
+        isSetter
+            ? interfaceSetters ?? classSetters
+            : interfaceMembers ?? classMembers);
+  }
+
+  Declaration findMember(Name name, List<Declaration> declarations) {
+    // TODO(ahe): Consider creating a map or scope. The obvious choice would be
+    // to use scopes, but they don't handle private names correctly.
+
+    // This is a copy of `ClassHierarchy.findMemberByName`.
+    int low = 0, high = declarations.length - 1;
+    while (low <= high) {
+      int mid = low + ((high - low) >> 1);
+      Declaration pivot = declarations[mid];
+      int comparison = ClassHierarchy.compareNames(name, pivot.target.name);
+      if (comparison < 0) {
+        high = mid - 1;
+      } else if (comparison > 0) {
+        low = mid + 1;
+      } else if (high != mid) {
+        // Ensure we find the first element of the given name.
+        high = mid;
+      } else {
+        return pivot;
+      }
+    }
+    return null;
+  }
+
+  Declaration getDispatchTarget(Name name, bool isSetter) {
+    return findMember(name, isSetter ? classSetters : classMembers);
+  }
+
   static int compareMaxInheritancePath(
       ClassHierarchyNode a, ClassHierarchyNode b) {
     return b.maxInheritancePath.compareTo(a.maxInheritancePath);
@@ -996,17 +1800,28 @@
 
 enum MergeKind {
   /// Merging superclass members with the current class.
-  superclass,
+  superclassMembers,
 
-  /// Merging two interfaces.
-  interfaces,
+  /// Merging superclass setters with the current class.
+  superclassSetters,
+
+  /// Merging members of two interfaces.
+  interfacesMembers,
+
+  /// Merging setters of two interfaces.
+  interfacesSetters,
 
   /// Merging class members with interface members.
-  supertypes,
+  supertypesMembers,
 
-  /// Merging members with inherited setters, or setters with inherited
-  /// members.
-  accessors,
+  /// Merging class setters with interface setters.
+  supertypesSetters,
+
+  /// Merging members with inherited setters.
+  membersWithSetters,
+
+  /// Merging setters with inherited members.
+  settersWithMembers,
 }
 
 List<LocatedMessage> inheritedConflictContext(Declaration a, Declaration b) {
@@ -1123,3 +1938,627 @@
     return hierarchy.getKernelLegacyLeastUpperBound(type1, type2);
   }
 }
+
+class DelayedOverrideCheck {
+  final KernelClassBuilder cls;
+  final Declaration a;
+  final Declaration b;
+
+  const DelayedOverrideCheck(this.cls, this.a, this.b);
+
+  void check(ClassHierarchyBuilder hierarchy) {
+    void callback(
+        Member declaredMember, Member interfaceMember, bool isSetter) {
+      cls.checkOverride(
+          hierarchy.types, declaredMember, interfaceMember, isSetter, callback,
+          isInterfaceCheck: !cls.isMixinApplication);
+    }
+
+    Declaration a = this.a;
+    debug?.log(
+        "Delayed override check of ${fullName(a)} ${fullName(b)} wrt. ${cls.fullNameForErrors}");
+    if (cls == a.parent) {
+      if (a is KernelProcedureBuilder) {
+        if (a.isGetter && !hasExplicitReturnType(a)) {
+          DartType type;
+          if (b.isGetter) {
+            Procedure bTarget = b.target;
+            type = bTarget.function.returnType;
+          } else if (b.isSetter) {
+            Procedure bTarget = b.target;
+            type = bTarget.function.positionalParameters.single.type;
+          } else if (b.isField) {
+            Field bTarget = b.target;
+            type = bTarget.type;
+          }
+          if (type != null) {
+            type = Substitution.fromInterfaceType(
+                    hierarchy.getKernelTypeAsInstanceOf(
+                        cls.cls.thisType, b.target.enclosingClass))
+                .substituteType(type);
+            if (!a.hadTypesInferred || !b.isSetter) {
+              inferReturnType(cls, a, type, a.hadTypesInferred, hierarchy);
+            }
+          }
+        } else if (a.isSetter && !hasExplictlyTypedFormalParameter(a, 0)) {
+          DartType type;
+          if (b.isGetter) {
+            Procedure bTarget = b.target;
+            type = bTarget.function.returnType;
+          } else if (b.isSetter) {
+            Procedure bTarget = b.target;
+            type = bTarget.function.positionalParameters.single.type;
+          } else if (b.isField) {
+            Field bTarget = b.target;
+            type = bTarget.type;
+          }
+          if (type != null) {
+            type = Substitution.fromInterfaceType(
+                    hierarchy.getKernelTypeAsInstanceOf(
+                        cls.cls.thisType, b.target.enclosingClass))
+                .substituteType(type);
+            if (!a.hadTypesInferred || !b.isGetter) {
+              inferParameterType(cls, a, a.formals.single, type,
+                  a.hadTypesInferred, hierarchy);
+            }
+          }
+        }
+        a.hadTypesInferred = true;
+      } else if (a is KernelFieldBuilder && a.type == null) {
+        DartType type;
+        if (b.isGetter) {
+          Procedure bTarget = b.target;
+          type = bTarget.function.returnType;
+        } else if (b.isSetter) {
+          Procedure bTarget = b.target;
+          type = bTarget.function.positionalParameters.single.type;
+        } else if (b.isField) {
+          Field bTarget = b.target;
+          type = bTarget.type;
+        }
+        if (type != null) {
+          type = Substitution.fromInterfaceType(
+                  hierarchy.getKernelTypeAsInstanceOf(
+                      cls.cls.thisType, b.target.enclosingClass))
+              .substituteType(type);
+          if (type != a.target.type) {
+            if (a.hadTypesInferred) {
+              if (b.isSetter &&
+                  (!impliesSetter(a) ||
+                      hierarchy.types.isSubtypeOfKernel(type, a.target.type))) {
+                type = a.target.type;
+              } else {
+                reportCantInferFieldType(cls, a);
+                type = const InvalidType();
+              }
+            }
+            debug?.log("Inferred type ${type} for ${fullName(a)}");
+            a.target.type = type;
+          }
+        }
+        a.hadTypesInferred = true;
+      }
+    }
+
+    callback(a.target, b.target, a.isSetter);
+  }
+}
+
+abstract class DelayedMember extends Declaration {
+  /// The class which has inherited [declarations].
+  @override
+  final KernelClassBuilder parent;
+
+  /// Conflicting declarations.
+  final List<Declaration> declarations;
+
+  final isSetter;
+
+  final bool modifyKernel;
+
+  DelayedMember(
+      this.parent, this.declarations, this.isSetter, this.modifyKernel);
+
+  void addAllDeclarationsTo(List<Declaration> declarations) {
+    for (int i = 0; i < this.declarations.length; i++) {
+      addDeclarationIfDifferent(this.declarations[i], declarations);
+    }
+    assert(declarations.toSet().length == declarations.length);
+  }
+
+  Member check(ClassHierarchyBuilder hierarchy);
+
+  DelayedMember withParent(KernelClassBuilder parent);
+
+  @override
+  Uri get fileUri => parent.fileUri;
+
+  @override
+  int get charOffset => parent.charOffset;
+
+  @override
+  String get fullNameForErrors => declarations.map(fullName).join("%");
+
+  @override
+  Member get target => declarations.first.target;
+}
+
+/// This represents a concrete implementation inherited from a superclass that
+/// has conflicts with methods inherited from an interface. The concrete
+/// implementation is the first element of [declarations].
+class InheritedImplementationInterfaceConflict extends DelayedMember {
+  Member combinedMemberSignatureResult;
+
+  InheritedImplementationInterfaceConflict(KernelClassBuilder parent,
+      List<Declaration> declarations, bool isSetter, bool modifyKernel)
+      : super(parent, declarations, isSetter, modifyKernel);
+
+  @override
+  String toString() {
+    return "InheritedImplementationInterfaceConflict("
+        "${parent.fullNameForErrors}, "
+        "[${declarations.map(fullName).join(', ')}])";
+  }
+
+  @override
+  Member check(ClassHierarchyBuilder hierarchy) {
+    if (combinedMemberSignatureResult != null) {
+      return combinedMemberSignatureResult;
+    }
+    if (!parent.isAbstract) {
+      Declaration concreteImplementation = declarations.first;
+      for (int i = 1; i < declarations.length; i++) {
+        new DelayedOverrideCheck(
+                parent, concreteImplementation, declarations[i])
+            .check(hierarchy);
+      }
+    }
+    return combinedMemberSignatureResult =
+        new InterfaceConflict(parent, declarations, isSetter, modifyKernel)
+            .check(hierarchy);
+  }
+
+  @override
+  DelayedMember withParent(KernelClassBuilder parent) {
+    return parent == this.parent
+        ? this
+        : new InheritedImplementationInterfaceConflict(
+            parent, declarations, isSetter, modifyKernel);
+  }
+
+  static Declaration combined(
+      KernelClassBuilder parent,
+      Declaration concreteImplementation,
+      Declaration other,
+      bool isSetter,
+      bool createForwarders) {
+    List<Declaration> declarations = <Declaration>[];
+    if (concreteImplementation is DelayedMember) {
+      concreteImplementation.addAllDeclarationsTo(declarations);
+    } else {
+      declarations.add(concreteImplementation);
+    }
+    if (other is DelayedMember) {
+      other.addAllDeclarationsTo(declarations);
+    } else {
+      addDeclarationIfDifferent(other, declarations);
+    }
+    if (declarations.length == 1) {
+      return declarations.single;
+    } else {
+      return new InheritedImplementationInterfaceConflict(
+          parent, declarations, isSetter, createForwarders);
+    }
+  }
+}
+
+class InterfaceConflict extends DelayedMember {
+  InterfaceConflict(KernelClassBuilder parent, List<Declaration> declarations,
+      bool isSetter, bool modifyKernel)
+      : super(parent, declarations, isSetter, modifyKernel);
+
+  Member combinedMemberSignatureResult;
+
+  @override
+  String toString() {
+    return "InterfaceConflict(${parent.fullNameForErrors}, "
+        "[${declarations.map(fullName).join(', ')}])";
+  }
+
+  DartType computeMemberType(
+      ClassHierarchyBuilder hierarchy, DartType thisType, Member member) {
+    DartType type;
+    if (member is Procedure) {
+      if (member.isGetter) {
+        type = member.getterType;
+      } else if (member.isSetter) {
+        type = member.setterType;
+      } else {
+        type = member.function.functionType;
+      }
+    } else if (member is Field) {
+      type = member.type;
+    } else {
+      unhandled("${member.runtimeType}", "$member", parent.charOffset,
+          parent.fileUri);
+    }
+    return Substitution.fromInterfaceType(hierarchy.getKernelTypeAsInstanceOf(
+            thisType, member.enclosingClass))
+        .substituteType(type);
+  }
+
+  bool isMoreSpecific(ClassHierarchyBuilder hierarchy, DartType a, DartType b) {
+    if (isSetter) {
+      return hierarchy.types.isSubtypeOfKernel(b, a);
+    } else {
+      return hierarchy.types.isSubtypeOfKernel(a, b);
+    }
+  }
+
+  @override
+  Member check(ClassHierarchyBuilder hierarchy) {
+    if (combinedMemberSignatureResult != null) {
+      return combinedMemberSignatureResult;
+    }
+    if (parent.library is! KernelLibraryBuilder) {
+      return combinedMemberSignatureResult = declarations.first.target;
+    }
+    DartType thisType = parent.cls.thisType;
+    Declaration bestSoFar;
+    DartType bestTypeSoFar;
+    for (int i = declarations.length - 1; i >= 0; i--) {
+      Declaration candidate = declarations[i];
+      Member target = candidate.target;
+      DartType candidateType = computeMemberType(hierarchy, thisType, target);
+      if (bestSoFar == null) {
+        bestSoFar = candidate;
+        bestTypeSoFar = candidateType;
+      } else {
+        if (isMoreSpecific(hierarchy, candidateType, bestTypeSoFar)) {
+          debug?.log(
+              "Combined Member Signature: ${fullName(candidate)} ${candidateType} <: ${fullName(bestSoFar)} ${bestTypeSoFar}");
+          bestSoFar = candidate;
+          bestTypeSoFar = candidateType;
+        } else {
+          debug?.log(
+              "Combined Member Signature: ${fullName(candidate)} !<: ${fullName(bestSoFar)}");
+        }
+      }
+    }
+    if (bestSoFar != null) {
+      debug?.log("Combined Member Signature bestSoFar: ${fullName(bestSoFar)}");
+      for (int i = 0; i < declarations.length; i++) {
+        Declaration candidate = declarations[i];
+        Member target = candidate.target;
+        DartType candidateType = computeMemberType(hierarchy, thisType, target);
+        if (!isMoreSpecific(hierarchy, bestTypeSoFar, candidateType)) {
+          debug?.log(
+              "Combined Member Signature: ${fullName(bestSoFar)} !<: ${fullName(candidate)}");
+
+          String uri = '${parent.library.uri}';
+          if (uri == 'dart:js' &&
+                  parent.fileUri.pathSegments.last == 'js_dart2js.dart' ||
+              uri == 'dart:_interceptors' &&
+                  parent.fileUri.pathSegments.last == 'js_number.dart') {
+            // TODO(johnniwinther): Fix the dart2js libraries and remove the
+            // above URIs.
+          } else {
+            bestSoFar = null;
+            bestTypeSoFar = null;
+          }
+          break;
+        }
+      }
+    }
+    if (bestSoFar == null) {
+      String name = parent.fullNameForErrors;
+      int length = parent.isAnonymousMixinApplication ? 1 : name.length;
+      List<LocatedMessage> context = declarations.map((Declaration d) {
+        return messageDeclaredMemberConflictsWithInheritedMemberCause
+            .withLocation(d.fileUri, d.charOffset, d.fullNameForErrors.length);
+      }).toList();
+
+      parent.addProblem(
+          templateCombinedMemberSignatureFailed.withArguments(
+              parent.fullNameForErrors, declarations.first.fullNameForErrors),
+          parent.charOffset,
+          length,
+          context: context);
+      return null;
+    }
+    debug?.log(
+        "Combined Member Signature of ${fullNameForErrors}: ${fullName(bestSoFar)}");
+
+    ProcedureKind kind = ProcedureKind.Method;
+    if (bestSoFar.isField || bestSoFar.isSetter || bestSoFar.isGetter) {
+      kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
+    }
+
+    if (modifyKernel) {
+      debug?.log(
+          "Combined Member Signature of ${fullNameForErrors}: new ForwardingNode($parent, $bestSoFar, $declarations, $kind)");
+      Member stub =
+          new ForwardingNode(hierarchy, parent, bestSoFar, declarations, kind)
+              .finalize();
+      if (parent.cls == stub.enclosingClass) {
+        parent.cls.addMember(stub);
+        KernelLibraryBuilder library = parent.library;
+        if (bestSoFar.target is Procedure) {
+          library.forwardersOrigins..add(stub)..add(bestSoFar.target);
+        }
+        debug?.log(
+            "Combined Member Signature of ${fullNameForErrors}: added stub $stub");
+        if (parent.isMixinApplication) {
+          return combinedMemberSignatureResult = bestSoFar.target;
+        } else {
+          return combinedMemberSignatureResult = stub;
+        }
+      }
+    }
+
+    debug?.log(
+        "Combined Member Signature of ${fullNameForErrors}: picked bestSoFar");
+    return combinedMemberSignatureResult = bestSoFar.target;
+  }
+
+  @override
+  DelayedMember withParent(KernelClassBuilder parent) {
+    return parent == this.parent
+        ? this
+        : new InterfaceConflict(parent, declarations, isSetter, modifyKernel);
+  }
+
+  static Declaration combined(KernelClassBuilder parent, Declaration a,
+      Declaration b, bool isSetter, bool createForwarders) {
+    List<Declaration> declarations = <Declaration>[];
+    if (a is DelayedMember) {
+      a.addAllDeclarationsTo(declarations);
+    } else {
+      declarations.add(a);
+    }
+    if (b is DelayedMember) {
+      b.addAllDeclarationsTo(declarations);
+    } else {
+      addDeclarationIfDifferent(b, declarations);
+    }
+    if (declarations.length == 1) {
+      return declarations.single;
+    } else {
+      return new InterfaceConflict(
+          parent, declarations, isSetter, createForwarders);
+    }
+  }
+}
+
+class AbstractMemberOverridingImplementation extends DelayedMember {
+  AbstractMemberOverridingImplementation(
+      KernelClassBuilder parent,
+      Declaration abstractMember,
+      Declaration concreteImplementation,
+      bool isSetter,
+      bool modifyKernel)
+      : super(parent, <Declaration>[concreteImplementation, abstractMember],
+            isSetter, modifyKernel);
+
+  Declaration get concreteImplementation => declarations[0];
+
+  Declaration get abstractMember => declarations[1];
+
+  Member check(ClassHierarchyBuilder hierarchy) {
+    if (!parent.isAbstract) {
+      new DelayedOverrideCheck(parent, concreteImplementation, abstractMember)
+          .check(hierarchy);
+    }
+
+    ProcedureKind kind = ProcedureKind.Method;
+    if (abstractMember.isSetter || abstractMember.isGetter) {
+      kind = isSetter ? ProcedureKind.Setter : ProcedureKind.Getter;
+    }
+    if (modifyKernel) {
+      // This call will add a body to the abstract method if needed for
+      // isGenericCovariantImpl checks.
+      new ForwardingNode(hierarchy, parent, abstractMember, declarations, kind)
+          .finalize();
+    }
+    return abstractMember.target;
+  }
+
+  @override
+  DelayedMember withParent(KernelClassBuilder parent) {
+    return parent == this.parent
+        ? this
+        : new AbstractMemberOverridingImplementation(parent, abstractMember,
+            concreteImplementation, isSetter, modifyKernel);
+  }
+
+  static Declaration selectAbstract(Declaration declaration) {
+    if (declaration is AbstractMemberOverridingImplementation) {
+      return declaration.abstractMember;
+    } else {
+      return declaration;
+    }
+  }
+
+  static Declaration selectConcrete(Declaration declaration) {
+    if (declaration is AbstractMemberOverridingImplementation) {
+      return declaration.concreteImplementation;
+    } else {
+      return declaration;
+    }
+  }
+}
+
+void addDeclarationIfDifferent(
+    Declaration declaration, List<Declaration> declarations) {
+  Member target = declaration.target;
+  if (target is Procedure) {
+    FunctionNode function = target.function;
+    for (int i = 0; i < declarations.length; i++) {
+      Member other = declarations[i].target;
+      if (other is Procedure) {
+        if (hasSameSignature(function, other.function)) return;
+      }
+    }
+  } else {
+    for (int i = 0; i < declarations.length; i++) {
+      if (declaration == declarations[i]) return;
+    }
+  }
+  declarations.add(declaration);
+}
+
+String fullName(Declaration declaration) {
+  if (declaration is DelayedMember) return declaration.fullNameForErrors;
+  Declaration parent = declaration.parent;
+  return parent == null
+      ? declaration.fullNameForErrors
+      : "${parent.fullNameForErrors}.${declaration.fullNameForErrors}";
+}
+
+int compareNamedParameters(VariableDeclaration a, VariableDeclaration b) {
+  return a.name.compareTo(b.name);
+}
+
+bool isAbstract(Declaration declaration) {
+  return declaration.target.isAbstract || declaration is InterfaceConflict;
+}
+
+bool inferParameterType(
+    KernelClassBuilder cls,
+    KernelProcedureBuilder member,
+    FormalParameterBuilder<KernelTypeBuilder> parameter,
+    DartType type,
+    bool hadTypesInferred,
+    ClassHierarchyBuilder hierarchy) {
+  debug?.log("Inferred type ${type} for ${parameter}");
+  if (type == parameter.target.type) return true;
+  bool result = true;
+  if (hadTypesInferred) {
+    reportCantInferParameterType(cls, member, parameter, hierarchy);
+    type = const InvalidType();
+    result = false;
+  }
+  parameter.target.type = type;
+  member.hadTypesInferred = true;
+  return result;
+}
+
+void reportCantInferParameterType(
+    KernelClassBuilder cls,
+    MemberBuilder member,
+    FormalParameterBuilder<KernelTypeBuilder> parameter,
+    ClassHierarchyBuilder hierarchy) {
+  String name = parameter.name;
+  cls.addProblem(
+      templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
+      parameter.charOffset,
+      name.length,
+      wasHandled: true);
+}
+
+bool inferReturnType(KernelClassBuilder cls, KernelProcedureBuilder member,
+    DartType type, bool hadTypesInferred, ClassHierarchyBuilder hierarchy) {
+  if (type == member.target.function.returnType) return true;
+  bool result = true;
+  if (hadTypesInferred) {
+    reportCantInferReturnType(cls, member, hierarchy);
+    type = const InvalidType();
+    result = false;
+  } else {
+    member.hadTypesInferred = true;
+  }
+  member.target.function.returnType = type;
+  return result;
+}
+
+void reportCantInferReturnType(KernelClassBuilder cls, MemberBuilder member,
+    ClassHierarchyBuilder hierarchy) {
+  String name = member.fullNameForErrors;
+  List<LocatedMessage> context;
+  // // TODO(ahe): The following is for debugging, but could be cleaned up and
+  // // used to improve this error message in general.
+  //
+  // context = <LocatedMessage>[];
+  // ClassHierarchyNode supernode = hierarchy.getNodeFromType(cls.supertype);
+  // // TODO(ahe): Wrong template.
+  // Template<Message Function(String)> template =
+  //     templateMissingImplementationCause;
+  // if (supernode != null) {
+  //   Declaration superMember =
+  //       supernode.getInterfaceMember(new Name(name), false);
+  //   if (superMember != null) {
+  //     context.add(template
+  //         .withArguments(name)
+  //         .withLocation(
+  //             superMember.fileUri, superMember.charOffset, name.length));
+  //   }
+  //   superMember = supernode.getInterfaceMember(new Name(name), true);
+  //   if (superMember != null) {
+  //     context.add(template
+  //         .withArguments(name)
+  //         .withLocation(
+  //             superMember.fileUri, superMember.charOffset, name.length));
+  //   }
+  // }
+  // List<KernelTypeBuilder> directInterfaces = cls.interfaces;
+  // for (int i = 0; i < directInterfaces.length; i++) {
+  //   ClassHierarchyNode supernode =
+  //       hierarchy.getNodeFromType(directInterfaces[i]);
+  //   if (supernode != null) {
+  //     Declaration superMember =
+  //         supernode.getInterfaceMember(new Name(name), false);
+  //     if (superMember != null) {
+  //       context.add(template
+  //           .withArguments(name)
+  //           .withLocation(
+  //               superMember.fileUri, superMember.charOffset, name.length));
+  //     }
+  //     superMember = supernode.getInterfaceMember(new Name(name), true);
+  //     if (superMember != null) {
+  //       context.add(template
+  //           .withArguments(name)
+  //           .withLocation(
+  //               superMember.fileUri, superMember.charOffset, name.length));
+  //     }
+  //   }
+  // }
+  cls.addProblem(
+      templateCantInferReturnTypeDueToInconsistentOverrides.withArguments(name),
+      member.charOffset,
+      name.length,
+      wasHandled: true,
+      context: context);
+}
+
+void reportCantInferFieldType(
+    KernelClassBuilder cls, KernelFieldBuilder member) {
+  String name = member.fullNameForErrors;
+  cls.addProblem(
+      templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
+      member.charOffset,
+      name.length,
+      wasHandled: true);
+}
+
+KernelClassBuilder getClass(KernelTypeBuilder type) {
+  Declaration declaration = type.declaration;
+  return declaration is KernelClassBuilder ? declaration : null;
+}
+
+bool hasExplicitReturnType(Declaration declaration) {
+  assert(
+      declaration is KernelProcedureBuilder || declaration is DillMemberBuilder,
+      "${declaration.runtimeType}");
+  return declaration is KernelProcedureBuilder
+      ? declaration.returnType != null
+      : true;
+}
+
+bool hasExplictlyTypedFormalParameter(Declaration declaration, int index) {
+  assert(
+      declaration is KernelProcedureBuilder || declaration is DillMemberBuilder,
+      "${declaration.runtimeType}");
+  return declaration is KernelProcedureBuilder
+      ? declaration.formals[index].type != null
+      : true;
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
new file mode 100644
index 0000000..441c827
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/forwarding_node.dart
@@ -0,0 +1,416 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:kernel/ast.dart"
+    show
+        Arguments,
+        Class,
+        DartType,
+        Expression,
+        Field,
+        FunctionNode,
+        Member,
+        Name,
+        NamedExpression,
+        Procedure,
+        ProcedureKind,
+        ReturnStatement,
+        SuperMethodInvocation,
+        SuperPropertyGet,
+        SuperPropertySet,
+        TypeParameter,
+        TypeParameterType,
+        VariableDeclaration,
+        VariableGet,
+        VoidType;
+
+import 'package:kernel/transformations/flags.dart' show TransformerFlag;
+
+import "package:kernel/type_algebra.dart" show Substitution;
+
+import "../problems.dart" show unhandled;
+
+import "../type_inference/type_inference_engine.dart"
+    show IncludesTypeParametersCovariantly;
+
+import "../type_inference/type_inferrer.dart" show getNamedFormal;
+
+import "kernel_builder.dart"
+    show ClassHierarchyBuilder, Declaration, DelayedMember, KernelClassBuilder;
+
+class ForwardingNode {
+  final ClassHierarchyBuilder hierarchy;
+
+  final KernelClassBuilder parent;
+
+  final Declaration combinedMemberSignatureResult;
+
+  final ProcedureKind kind;
+
+  /// A list containing the directly implemented and directly inherited
+  /// procedures of the class in question.
+  final List<Declaration> _candidates;
+
+  ForwardingNode(this.hierarchy, this.parent,
+      this.combinedMemberSignatureResult, this._candidates, this.kind);
+
+  Name get name => combinedMemberSignatureResult.target.name;
+
+  Class get enclosingClass => parent.cls;
+
+  /// Finishes handling of this node by propagating covariance and creating
+  /// forwarding stubs if necessary.
+  Member finalize() => _computeCovarianceFixes();
+
+  /// Tag the parameters of [interfaceMember] that need type checks
+  ///
+  /// Parameters can need type checks for calls coming from statically typed
+  /// call sites, due to covariant generics and overrides with explicit
+  /// `covariant` parameters.
+  ///
+  /// Tag parameters of [interfaceMember] that need such checks when the member
+  /// occurs in [enclosingClass]'s interface.  If parameters need checks but
+  /// they would not be checked in an inherited implementation, a forwarding
+  /// stub is introduced as a place to put the checks.
+  Member _computeCovarianceFixes() {
+    Member interfaceMember = combinedMemberSignatureResult.target;
+    Substitution substitution =
+        _substitutionFor(interfaceMember, enclosingClass);
+    // We always create a forwarding stub when we've inherited a member from an
+    // interface other than the first override candidate.  This is to work
+    // around a bug in the Kernel type checker where it chooses the first
+    // override candidate.
+    //
+    // TODO(kmillikin): Fix the Kernel type checker and stop creating these
+    // extra stubs.
+    Member stub = interfaceMember.enclosingClass == enclosingClass ||
+            interfaceMember == getCandidateAt(0)
+        ? interfaceMember
+        : _createForwardingStub(substitution, interfaceMember);
+
+    FunctionNode interfaceFunction = interfaceMember.function;
+    List<VariableDeclaration> interfacePositionalParameters =
+        getPositionalParameters(interfaceMember);
+    List<VariableDeclaration> interfaceNamedParameters =
+        interfaceFunction?.namedParameters ?? [];
+    List<TypeParameter> interfaceTypeParameters =
+        interfaceFunction?.typeParameters ?? [];
+
+    void createStubIfNeeded() {
+      if (stub != interfaceMember) return;
+      if (interfaceMember.enclosingClass == enclosingClass) return;
+      stub = _createForwardingStub(substitution, interfaceMember);
+    }
+
+    bool isImplCreated = false;
+    void createImplIfNeeded() {
+      if (isImplCreated) return;
+      createStubIfNeeded();
+      _createForwardingImplIfNeeded(stub.function);
+      isImplCreated = true;
+    }
+
+    IncludesTypeParametersCovariantly needsCheckVisitor = enclosingClass
+            .typeParameters.isEmpty
+        ? null
+        // TODO(ahe): It may be necessary to cache this object.
+        : new IncludesTypeParametersCovariantly(enclosingClass.typeParameters);
+    bool needsCheck(DartType type) => needsCheckVisitor == null
+        ? false
+        : substitution.substituteType(type).accept(needsCheckVisitor);
+    for (int i = 0; i < interfacePositionalParameters.length; i++) {
+      VariableDeclaration parameter = interfacePositionalParameters[i];
+      bool isGenericCovariantImpl =
+          parameter.isGenericCovariantImpl || needsCheck(parameter.type);
+      bool isCovariant = parameter.isCovariant;
+      VariableDeclaration superParameter = parameter;
+      for (int j = 0; j < _candidates.length; j++) {
+        Member otherMember = getCandidateAt(j);
+        if (otherMember is ForwardingNode) continue;
+        List<VariableDeclaration> otherPositionalParameters =
+            getPositionalParameters(otherMember);
+        if (otherPositionalParameters.length <= i) continue;
+        VariableDeclaration otherParameter = otherPositionalParameters[i];
+        if (j == 0) superParameter = otherParameter;
+        if (identical(otherMember, interfaceMember)) continue;
+        if (otherParameter.isGenericCovariantImpl) {
+          isGenericCovariantImpl = true;
+        }
+        if (otherParameter.isCovariant) {
+          isCovariant = true;
+        }
+      }
+      if (isGenericCovariantImpl) {
+        if (!superParameter.isGenericCovariantImpl) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isGenericCovariantImpl) {
+          createStubIfNeeded();
+          stub.function.positionalParameters[i].isGenericCovariantImpl = true;
+        }
+      }
+      if (isCovariant) {
+        if (!superParameter.isCovariant) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isCovariant) {
+          createStubIfNeeded();
+          stub.function.positionalParameters[i].isCovariant = true;
+        }
+      }
+    }
+    for (int i = 0; i < interfaceNamedParameters.length; i++) {
+      VariableDeclaration parameter = interfaceNamedParameters[i];
+      bool isGenericCovariantImpl =
+          parameter.isGenericCovariantImpl || needsCheck(parameter.type);
+      bool isCovariant = parameter.isCovariant;
+      VariableDeclaration superParameter = parameter;
+      for (int j = 0; j < _candidates.length; j++) {
+        Member otherMember = getCandidateAt(j);
+        if (otherMember is ForwardingNode) continue;
+        VariableDeclaration otherParameter =
+            getNamedFormal(otherMember.function, parameter.name);
+        if (otherParameter == null) continue;
+        if (j == 0) superParameter = otherParameter;
+        if (identical(otherMember, interfaceMember)) continue;
+        if (otherParameter.isGenericCovariantImpl) {
+          isGenericCovariantImpl = true;
+        }
+        if (otherParameter.isCovariant) {
+          isCovariant = true;
+        }
+      }
+      if (isGenericCovariantImpl) {
+        if (!superParameter.isGenericCovariantImpl) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isGenericCovariantImpl) {
+          createStubIfNeeded();
+          stub.function.namedParameters[i].isGenericCovariantImpl = true;
+        }
+      }
+      if (isCovariant) {
+        if (!superParameter.isCovariant) {
+          createImplIfNeeded();
+        }
+        if (!parameter.isCovariant) {
+          createStubIfNeeded();
+          stub.function.namedParameters[i].isCovariant = true;
+        }
+      }
+    }
+    for (int i = 0; i < interfaceTypeParameters.length; i++) {
+      TypeParameter typeParameter = interfaceTypeParameters[i];
+      bool isGenericCovariantImpl = typeParameter.isGenericCovariantImpl ||
+          needsCheck(typeParameter.bound);
+      TypeParameter superTypeParameter = typeParameter;
+      for (int j = 0; j < _candidates.length; j++) {
+        Member otherMember = getCandidateAt(j);
+        if (otherMember is ForwardingNode) continue;
+        List<TypeParameter> otherTypeParameters =
+            otherMember.function.typeParameters;
+        if (otherTypeParameters.length <= i) continue;
+        TypeParameter otherTypeParameter = otherTypeParameters[i];
+        if (j == 0) superTypeParameter = otherTypeParameter;
+        if (identical(otherMember, interfaceMember)) continue;
+        if (otherTypeParameter.isGenericCovariantImpl) {
+          isGenericCovariantImpl = true;
+        }
+      }
+      if (isGenericCovariantImpl) {
+        if (!superTypeParameter.isGenericCovariantImpl) {
+          createImplIfNeeded();
+        }
+        if (!typeParameter.isGenericCovariantImpl) {
+          createStubIfNeeded();
+          stub.function.typeParameters[i].isGenericCovariantImpl = true;
+        }
+      }
+    }
+    return stub;
+  }
+
+  void _createForwardingImplIfNeeded(FunctionNode function) {
+    if (function.body != null) {
+      // There is already an implementation; nothing further needs to be done.
+      return;
+    }
+    // Find the concrete implementation in the superclass; this is what we need
+    // to forward to.  If we can't find one, then the method is fully abstract
+    // and we don't need to do anything.
+    Class superclass = enclosingClass.superclass;
+    if (superclass == null) return;
+    Procedure procedure = function.parent;
+    Member superTarget = hierarchy.getDispatchTargetKernel(
+        superclass, procedure.name, kind == ProcedureKind.Setter);
+    if (superTarget == null) return;
+    if (superTarget is Procedure && superTarget.isForwardingStub) {
+      superTarget = _getForwardingStubSuperTarget(superTarget);
+    }
+    procedure.isAbstract = false;
+    if (!procedure.isForwardingStub) {
+      // This procedure exists abstractly in the source code; we need to make it
+      // concrete and give it a body that is a forwarding stub.  This situation
+      // is called a "forwarding semi-stub".
+      procedure.isForwardingStub = true;
+      procedure.isForwardingSemiStub = true;
+    }
+    List<Expression> positionalArguments = function.positionalParameters
+        .map<Expression>((parameter) => new VariableGet(parameter))
+        .toList();
+    List<NamedExpression> namedArguments = function.namedParameters
+        .map((parameter) =>
+            new NamedExpression(parameter.name, new VariableGet(parameter)))
+        .toList();
+    List<DartType> typeArguments = function.typeParameters
+        .map<DartType>((typeParameter) => new TypeParameterType(typeParameter))
+        .toList();
+    Arguments arguments = new Arguments(positionalArguments,
+        types: typeArguments, named: namedArguments);
+    Expression superCall;
+    switch (kind) {
+      case ProcedureKind.Method:
+      case ProcedureKind.Operator:
+        superCall = new SuperMethodInvocation(name, arguments, superTarget);
+        break;
+      case ProcedureKind.Getter:
+        superCall = new SuperPropertyGet(name, superTarget);
+        break;
+      case ProcedureKind.Setter:
+        superCall =
+            new SuperPropertySet(name, positionalArguments[0], superTarget);
+        break;
+      default:
+        unhandled('$kind', '_createForwardingImplIfNeeded', -1, null);
+        break;
+    }
+    function.body = new ReturnStatement(superCall)..parent = function;
+    procedure.transformerFlags |= TransformerFlag.superCalls;
+    procedure.forwardingStubSuperTarget = superTarget;
+  }
+
+  /// Creates a forwarding stub based on the given [target].
+  Procedure _createForwardingStub(Substitution substitution, Member target) {
+    VariableDeclaration copyParameter(VariableDeclaration parameter) {
+      return new VariableDeclaration(parameter.name,
+          type: substitution.substituteType(parameter.type),
+          isCovariant: parameter.isCovariant)
+        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl;
+    }
+
+    List<TypeParameter> targetTypeParameters =
+        target.function?.typeParameters ?? [];
+    List<TypeParameter> typeParameters;
+    if (targetTypeParameters.isNotEmpty) {
+      typeParameters =
+          new List<TypeParameter>.filled(targetTypeParameters.length, null);
+      Map<TypeParameter, DartType> additionalSubstitution =
+          <TypeParameter, DartType>{};
+      for (int i = 0; i < targetTypeParameters.length; i++) {
+        TypeParameter targetTypeParameter = targetTypeParameters[i];
+        TypeParameter typeParameter = new TypeParameter(
+            targetTypeParameter.name, null)
+          ..isGenericCovariantImpl = targetTypeParameter.isGenericCovariantImpl;
+        typeParameters[i] = typeParameter;
+        additionalSubstitution[targetTypeParameter] =
+            new TypeParameterType(typeParameter);
+      }
+      substitution = Substitution.combine(
+          substitution, Substitution.fromMap(additionalSubstitution));
+      for (int i = 0; i < typeParameters.length; i++) {
+        typeParameters[i].bound =
+            substitution.substituteType(targetTypeParameters[i].bound);
+      }
+    }
+    List<VariableDeclaration> positionalParameters =
+        getPositionalParameters(target).map(copyParameter).toList();
+    List<VariableDeclaration> namedParameters =
+        target.function?.namedParameters?.map(copyParameter)?.toList() ?? [];
+    FunctionNode function = new FunctionNode(null,
+        positionalParameters: positionalParameters,
+        namedParameters: namedParameters,
+        typeParameters: typeParameters,
+        requiredParameterCount: getRequiredParameterCount(target),
+        returnType: substitution.substituteType(getReturnType(target)));
+    Member finalTarget;
+    if (target is Procedure && target.isForwardingStub) {
+      finalTarget = target.forwardingStubInterfaceTarget;
+    } else {
+      finalTarget = target;
+    }
+    return new Procedure(name, kind, function,
+        isAbstract: true,
+        isForwardingStub: true,
+        fileUri: enclosingClass.fileUri,
+        forwardingStubInterfaceTarget: finalTarget)
+      ..startFileOffset = enclosingClass.fileOffset
+      ..fileOffset = enclosingClass.fileOffset
+      ..parent = enclosingClass;
+  }
+
+  /// Returns the [i]th element of [_candidates], finalizing it if necessary.
+  Member getCandidateAt(int i) {
+    Declaration candidate = _candidates[i];
+    assert(candidate is! DelayedMember);
+    return candidate.target;
+  }
+
+  static Member _getForwardingStubSuperTarget(Procedure forwardingStub) {
+    // TODO(paulberry): when dartbug.com/31562 is fixed, this should become
+    // easier.
+    ReturnStatement body = forwardingStub.function.body;
+    Expression expression = body.expression;
+    if (expression is SuperMethodInvocation) {
+      return expression.interfaceTarget;
+    } else if (expression is SuperPropertySet) {
+      return expression.interfaceTarget;
+    } else {
+      return unhandled('${expression.runtimeType}',
+          '_getForwardingStubSuperTarget', -1, null);
+    }
+  }
+
+  Substitution _substitutionFor(Member candidate, Class class_) {
+    return Substitution.fromInterfaceType(hierarchy.getKernelTypeAsInstanceOf(
+        class_.thisType, candidate.enclosingClass));
+  }
+
+  List<VariableDeclaration> getPositionalParameters(Member member) {
+    if (member is Field) {
+      if (kind == ProcedureKind.Setter) {
+        return <VariableDeclaration>[
+          new VariableDeclaration("_",
+              type: member.type, isCovariant: member.isCovariant)
+            ..isGenericCovariantImpl = member.isGenericCovariantImpl
+        ];
+      } else {
+        return <VariableDeclaration>[];
+      }
+    } else {
+      return member.function.positionalParameters;
+    }
+  }
+
+  int getRequiredParameterCount(Member member) {
+    switch (kind) {
+      case ProcedureKind.Getter:
+        return 0;
+      case ProcedureKind.Setter:
+        return 1;
+      default:
+        return member.function.requiredParameterCount;
+    }
+  }
+
+  DartType getReturnType(Member member) {
+    switch (kind) {
+      case ProcedureKind.Getter:
+        return member is Field ? member.type : member.function.returnType;
+      case ProcedureKind.Setter:
+        return const VoidType();
+      default:
+        return member.function.returnType;
+    }
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index fedc609..1074242 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -16,6 +16,7 @@
 class ImplicitFieldType extends DartType {
   final MemberBuilder member;
   Token initializerToken;
+  bool isStarted = false;
 
   get nullability =>
       unsupported("nullability", member.charOffset, member.fileUri);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
index 0206595..146b7b2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_builder.dart
@@ -16,7 +16,8 @@
 
 export '../builder/builder.dart';
 
-export 'class_hierarchy_builder.dart' show ClassHierarchyBuilder;
+export 'class_hierarchy_builder.dart'
+    show ClassHierarchyBuilder, DelayedMember, DelayedOverrideCheck;
 
 export 'implicit_field_type.dart' show ImplicitFieldType;
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index b36770c..fd09cca 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -123,6 +123,8 @@
 
 import 'kernel_target.dart' show KernelTarget;
 
+import 'types.dart' show Types;
+
 abstract class KernelClassBuilder
     extends ClassBuilder<KernelTypeBuilder, InterfaceType> {
   KernelClassBuilder actualOrigin;
@@ -538,7 +540,7 @@
   }
 
   void handleSeenCovariant(
-      ClassHierarchy hierarchy,
+      Types types,
       Member declaredMember,
       Member interfaceMember,
       bool isSetter,
@@ -546,9 +548,8 @@
     // When a parameter is covariant we have to check that we also
     // override the same member in all parents.
     for (Supertype supertype in interfaceMember.enclosingClass.supers) {
-      Member m = hierarchy.getInterfaceMember(
-          supertype.classNode, interfaceMember.name,
-          setter: isSetter);
+      Member m = types.hierarchy.getInterfaceMemberKernel(
+          supertype.classNode, interfaceMember.name, isSetter);
       if (m != null) {
         callback(declaredMember, m, isSetter);
       }
@@ -556,8 +557,7 @@
   }
 
   void checkOverride(
-      ClassHierarchy hierarchy,
-      TypeEnvironment typeEnvironment,
+      Types types,
       Member declaredMember,
       Member interfaceMember,
       bool isSetter,
@@ -573,25 +573,25 @@
     if (declaredMember is Procedure && interfaceMember is Procedure) {
       if (declaredMember.kind == ProcedureKind.Method &&
           interfaceMember.kind == ProcedureKind.Method) {
-        bool seenCovariant = checkMethodOverride(hierarchy, typeEnvironment,
-            declaredMember, interfaceMember, isInterfaceCheck);
+        bool seenCovariant = checkMethodOverride(
+            types, declaredMember, interfaceMember, isInterfaceCheck);
         if (seenCovariant) {
           handleSeenCovariant(
-              hierarchy, declaredMember, interfaceMember, isSetter, callback);
+              types, declaredMember, interfaceMember, isSetter, callback);
         }
       }
       if (declaredMember.kind == ProcedureKind.Getter &&
           interfaceMember.kind == ProcedureKind.Getter) {
-        checkGetterOverride(hierarchy, typeEnvironment, declaredMember,
-            interfaceMember, isInterfaceCheck);
+        checkGetterOverride(
+            types, declaredMember, interfaceMember, isInterfaceCheck);
       }
       if (declaredMember.kind == ProcedureKind.Setter &&
           interfaceMember.kind == ProcedureKind.Setter) {
-        bool seenCovariant = checkSetterOverride(hierarchy, typeEnvironment,
-            declaredMember, interfaceMember, isInterfaceCheck);
+        bool seenCovariant = checkSetterOverride(
+            types, declaredMember, interfaceMember, isInterfaceCheck);
         if (seenCovariant) {
           handleSeenCovariant(
-              hierarchy, declaredMember, interfaceMember, isSetter, callback);
+              types, declaredMember, interfaceMember, isSetter, callback);
         }
       }
     } else {
@@ -599,19 +599,24 @@
           declaredMember is Procedure && declaredMember.isGetter;
       bool interfaceMemberHasGetter = interfaceMember is Field ||
           interfaceMember is Procedure && interfaceMember.isGetter;
-      bool declaredMemberHasSetter = declaredMember is Field ||
+      bool declaredMemberHasSetter = (declaredMember is Field &&
+              !declaredMember.isFinal &&
+              !declaredMember.isConst) ||
           declaredMember is Procedure && declaredMember.isSetter;
-      bool interfaceMemberHasSetter = interfaceMember is Field ||
+      bool interfaceMemberHasSetter = (interfaceMember is Field &&
+              !interfaceMember.isFinal &&
+              !interfaceMember.isConst) ||
           interfaceMember is Procedure && interfaceMember.isSetter;
       if (declaredMemberHasGetter && interfaceMemberHasGetter) {
-        checkGetterOverride(hierarchy, typeEnvironment, declaredMember,
-            interfaceMember, isInterfaceCheck);
-      } else if (declaredMemberHasSetter && interfaceMemberHasSetter) {
-        bool seenCovariant = checkSetterOverride(hierarchy, typeEnvironment,
-            declaredMember, interfaceMember, isInterfaceCheck);
+        checkGetterOverride(
+            types, declaredMember, interfaceMember, isInterfaceCheck);
+      }
+      if (declaredMemberHasSetter && interfaceMemberHasSetter) {
+        bool seenCovariant = checkSetterOverride(
+            types, declaredMember, interfaceMember, isInterfaceCheck);
         if (seenCovariant) {
           handleSeenCovariant(
-              hierarchy, declaredMember, interfaceMember, isSetter, callback);
+              types, declaredMember, interfaceMember, isSetter, callback);
         }
       }
     }
@@ -619,85 +624,10 @@
   }
 
   void checkOverrides(
-      ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {
-    void overridePairCallback(
-        Member declaredMember, Member interfaceMember, bool isSetter) {
-      checkOverride(hierarchy, typeEnvironment, declaredMember, interfaceMember,
-          isSetter, overridePairCallback);
-    }
-
-    hierarchy.forEachOverridePair(cls, overridePairCallback);
-  }
+      ClassHierarchy hierarchy, TypeEnvironment typeEnvironment) {}
 
   void checkAbstractMembers(CoreTypes coreTypes, ClassHierarchy hierarchy,
-      TypeEnvironment typeEnvironment) {
-    // TODO(ahe): Move this to [ClassHierarchyBuilder].
-    if (isAbstract) {
-      // Unimplemented members allowed
-      return;
-    }
-
-    bool mustHaveImplementation(Member member) {
-      // Public member
-      if (!member.name.isPrivate) return true;
-      // Private member in different library
-      if (member.enclosingLibrary != cls.enclosingLibrary) return false;
-      // Private member in patch
-      if (member.fileUri != member.enclosingClass.fileUri) return false;
-      // Private member in same library
-      return true;
-    }
-
-    void overridePairCallback(
-        Member declaredMember, Member interfaceMember, bool isSetter) {
-      checkOverride(hierarchy, typeEnvironment, declaredMember, interfaceMember,
-          isSetter, overridePairCallback,
-          isInterfaceCheck: true);
-    }
-
-    void findMissingImplementations({bool setters}) {
-      List<Member> dispatchTargets =
-          hierarchy.getDispatchTargets(cls, setters: setters);
-      int targetIndex = 0;
-      for (Member interfaceMember
-          in hierarchy.getInterfaceMembers(cls, setters: setters)) {
-        if (mustHaveImplementation(interfaceMember)) {
-          while (targetIndex < dispatchTargets.length &&
-              ClassHierarchy.compareMembers(
-                      dispatchTargets[targetIndex], interfaceMember) <
-                  0) {
-            targetIndex++;
-          }
-          bool foundTarget = targetIndex < dispatchTargets.length &&
-              ClassHierarchy.compareMembers(
-                      dispatchTargets[targetIndex], interfaceMember) <=
-                  0;
-          if (foundTarget) {
-            Member dispatchTarget = dispatchTargets[targetIndex];
-            while (dispatchTarget is Procedure &&
-                !dispatchTarget.isExternal &&
-                dispatchTarget.forwardingStubSuperTarget != null) {
-              dispatchTarget =
-                  (dispatchTarget as Procedure).forwardingStubSuperTarget;
-            }
-            while (interfaceMember is Procedure &&
-                !interfaceMember.isExternal &&
-                interfaceMember.forwardingStubInterfaceTarget != null) {
-              interfaceMember =
-                  (interfaceMember as Procedure).forwardingStubInterfaceTarget;
-            }
-            if (!hierarchy.isSubtypeOf(dispatchTarget.enclosingClass,
-                interfaceMember.enclosingClass)) {
-              overridePairCallback(dispatchTarget, interfaceMember, setters);
-            }
-          }
-        }
-      }
-    }
-
-    findMissingImplementations(setters: false);
-    findMissingImplementations(setters: true);
-  }
+      TypeEnvironment typeEnvironment) {}
 
   bool hasUserDefinedNoSuchMethod(
       Class klass, ClassHierarchy hierarchy, Class objectClass) {
@@ -924,7 +854,7 @@
   }
 
   Substitution _computeInterfaceSubstitution(
-      ClassHierarchy hierarchy,
+      Types types,
       Member declaredMember,
       Member interfaceMember,
       FunctionNode declaredFunction,
@@ -932,8 +862,9 @@
       bool isInterfaceCheck) {
     Substitution interfaceSubstitution = Substitution.empty;
     if (interfaceMember.enclosingClass.typeParameters.isNotEmpty) {
-      interfaceSubstitution = Substitution.fromSupertype(
-          hierarchy.getClassAsInstanceOf(cls, interfaceMember.enclosingClass));
+      interfaceSubstitution = Substitution.fromInterfaceType(types.hierarchy
+          .getKernelTypeAsInstanceOf(
+              cls.thisType, interfaceMember.enclosingClass));
     }
     if (declaredFunction?.typeParameters?.length !=
         interfaceFunction?.typeParameters?.length) {
@@ -1000,17 +931,18 @@
   }
 
   Substitution _computeDeclaredSubstitution(
-      ClassHierarchy hierarchy, Member declaredMember) {
+      Types types, Member declaredMember) {
     Substitution declaredSubstitution = Substitution.empty;
     if (declaredMember.enclosingClass.typeParameters.isNotEmpty) {
-      declaredSubstitution = Substitution.fromSupertype(
-          hierarchy.getClassAsInstanceOf(cls, declaredMember.enclosingClass));
+      declaredSubstitution = Substitution.fromInterfaceType(types.hierarchy
+          .getKernelTypeAsInstanceOf(
+              cls.thisType, declaredMember.enclosingClass));
     }
     return declaredSubstitution;
   }
 
-  bool _checkTypes(
-      TypeEnvironment typeEnvironment,
+  void _checkTypes(
+      Types types,
       Substitution interfaceSubstitution,
       Substitution declaredSubstitution,
       Member declaredMember,
@@ -1021,7 +953,7 @@
       VariableDeclaration declaredParameter,
       bool isInterfaceCheck,
       {bool asIfDeclaredParameter = false}) {
-    if (library.loader.target.backendTarget.legacyMode) return false;
+    if (library.loader.target.backendTarget.legacyMode) return;
 
     if (interfaceSubstitution != null) {
       interfaceType = interfaceSubstitution.substituteType(interfaceType);
@@ -1034,9 +966,9 @@
     DartType subtype = inParameter ? interfaceType : declaredType;
     DartType supertype = inParameter ? declaredType : interfaceType;
 
-    if (typeEnvironment.isSubtypeOf(subtype, supertype)) {
+    if (types.isSubtypeOfKernel(subtype, supertype)) {
       // No problem--the proper subtyping relation is satisfied.
-    } else if (isCovariant && typeEnvironment.isSubtypeOf(supertype, subtype)) {
+    } else if (isCovariant && types.isSubtypeOfKernel(supertype, subtype)) {
       // No problem--the overriding parameter is marked "covariant" and has
       // a type which is a subtype of the parameter it overrides.
     } else if (subtype is InvalidType || supertype is InvalidType) {
@@ -1074,19 +1006,13 @@
                         interfaceMember.fileOffset, noLength)
               ] +
               inheritedContext(isInterfaceCheck, declaredMember));
-      return true;
     }
-    return false;
   }
 
   /// Returns whether a covariant parameter was seen and more methods thus have
   /// to be checked.
-  bool checkMethodOverride(
-      ClassHierarchy hierarchy,
-      TypeEnvironment typeEnvironment,
-      Procedure declaredMember,
-      Procedure interfaceMember,
-      bool isInterfaceCheck) {
+  bool checkMethodOverride(Types types, Procedure declaredMember,
+      Procedure interfaceMember, bool isInterfaceCheck) {
     assert(declaredMember.kind == ProcedureKind.Method);
     assert(interfaceMember.kind == ProcedureKind.Method);
     bool seenCovariant = false;
@@ -1094,7 +1020,7 @@
     FunctionNode interfaceFunction = interfaceMember.function;
 
     Substitution interfaceSubstitution = _computeInterfaceSubstitution(
-        hierarchy,
+        types,
         declaredMember,
         interfaceMember,
         declaredFunction,
@@ -1102,10 +1028,10 @@
         isInterfaceCheck);
 
     Substitution declaredSubstitution =
-        _computeDeclaredSubstitution(hierarchy, declaredMember);
+        _computeDeclaredSubstitution(types, declaredMember);
 
     _checkTypes(
-        typeEnvironment,
+        types,
         interfaceSubstitution,
         declaredSubstitution,
         declaredMember,
@@ -1160,7 +1086,7 @@
       var declaredParameter = declaredFunction.positionalParameters[i];
       var interfaceParameter = interfaceFunction.positionalParameters[i];
       _checkTypes(
-          typeEnvironment,
+          types,
           interfaceSubstitution,
           declaredSubstitution,
           declaredMember,
@@ -1237,7 +1163,7 @@
       }
       var declaredParameter = declaredNamedParameters.current;
       _checkTypes(
-          typeEnvironment,
+          types,
           interfaceSubstitution,
           declaredSubstitution,
           declaredMember,
@@ -1252,25 +1178,16 @@
     return seenCovariant;
   }
 
-  void checkGetterOverride(
-      ClassHierarchy hierarchy,
-      TypeEnvironment typeEnvironment,
-      Member declaredMember,
-      Member interfaceMember,
-      bool isInterfaceCheck) {
+  void checkGetterOverride(Types types, Member declaredMember,
+      Member interfaceMember, bool isInterfaceCheck) {
     Substitution interfaceSubstitution = _computeInterfaceSubstitution(
-        hierarchy,
-        declaredMember,
-        interfaceMember,
-        null,
-        null,
-        isInterfaceCheck);
+        types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
     Substitution declaredSubstitution =
-        _computeDeclaredSubstitution(hierarchy, declaredMember);
+        _computeDeclaredSubstitution(types, declaredMember);
     var declaredType = declaredMember.getterType;
     var interfaceType = interfaceMember.getterType;
     _checkTypes(
-        typeEnvironment,
+        types,
         interfaceSubstitution,
         declaredSubstitution,
         declaredMember,
@@ -1284,29 +1201,25 @@
 
   /// Returns whether a covariant parameter was seen and more methods thus have
   /// to be checked.
-  bool checkSetterOverride(
-      ClassHierarchy hierarchy,
-      TypeEnvironment typeEnvironment,
-      Member declaredMember,
-      Member interfaceMember,
-      bool isInterfaceCheck) {
+  bool checkSetterOverride(Types types, Member declaredMember,
+      Member interfaceMember, bool isInterfaceCheck) {
     Substitution interfaceSubstitution = _computeInterfaceSubstitution(
-        hierarchy,
-        declaredMember,
-        interfaceMember,
-        null,
-        null,
-        isInterfaceCheck);
+        types, declaredMember, interfaceMember, null, null, isInterfaceCheck);
     Substitution declaredSubstitution =
-        _computeDeclaredSubstitution(hierarchy, declaredMember);
+        _computeDeclaredSubstitution(types, declaredMember);
     var declaredType = declaredMember.setterType;
     var interfaceType = interfaceMember.setterType;
     var declaredParameter =
         declaredMember.function?.positionalParameters?.elementAt(0);
     bool isCovariant = declaredParameter?.isCovariant ?? false;
-    if (declaredMember is Field) isCovariant = declaredMember.isCovariant;
+    if (!isCovariant && declaredMember is Field) {
+      isCovariant = declaredMember.isCovariant;
+    }
+    if (!isCovariant && interfaceMember is Field) {
+      isCovariant = interfaceMember.isCovariant;
+    }
     _checkTypes(
-        typeEnvironment,
+        types,
         interfaceSubstitution,
         declaredSubstitution,
         declaredMember,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
index 484c95e..8ee7d22 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
@@ -25,8 +25,6 @@
         ThisExpression,
         VariableGet;
 
-import 'kernel_shadow_ast.dart' show ShadowClass;
-
 import '../fasta_codes.dart'
     show
         LocatedMessage,
@@ -85,7 +83,7 @@
       String name,
       Scope scope,
       Scope constructors,
-      ShadowClass cls,
+      Class cls,
       this.enumConstantInfos,
       this.intType,
       this.listType,
@@ -115,7 +113,7 @@
     KernelTypeBuilder stringType = new KernelNamedTypeBuilder("String", null);
     KernelNamedTypeBuilder objectType =
         new KernelNamedTypeBuilder("Object", null);
-    ShadowClass cls = new ShadowClass(name: name);
+    Class cls = new Class(name: name);
     Map<String, MemberBuilder> members = <String, MemberBuilder>{};
     Map<String, MemberBuilder> constructors = <String, MemberBuilder>{};
     KernelNamedTypeBuilder selfType = new KernelNamedTypeBuilder(name, null);
@@ -255,7 +253,6 @@
     members.forEach(setParent);
     constructors.forEach(setParent);
     selfType.bind(enumBuilder);
-    ShadowClass.setBuilder(cls, enumBuilder);
     return enumBuilder;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
index 88a91b4..d750874 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
@@ -5,13 +5,16 @@
 library fasta.kernel_field_builder;
 
 import 'package:kernel/ast.dart'
-    show Class, DartType, DynamicType, Expression, Field, Name, NullLiteral;
+    show Class, DartType, Expression, Field, InvalidType, Name, NullLiteral;
 
 import '../constant_context.dart' show ConstantContext;
 
-import '../fasta_codes.dart' show messageInternalProblemAlreadyInitialized;
+import '../fasta_codes.dart'
+    show
+        messageInternalProblemAlreadyInitialized,
+        templateCantInferTypeDueToCircularity;
 
-import '../problems.dart' show internalProblem, unsupported;
+import '../problems.dart' show internalProblem;
 
 import '../scanner.dart' show Token;
 
@@ -22,6 +25,10 @@
 import '../type_inference/type_inference_engine.dart'
     show IncludesTypeParametersCovariantly;
 
+import '../type_inference/type_inferrer.dart' show TypeInferrerImpl;
+
+import '../type_inference/type_schema.dart' show UnknownType;
+
 import 'kernel_body_builder.dart' show KernelBodyBuilder;
 
 import 'kernel_builder.dart'
@@ -36,18 +43,17 @@
         LibraryBuilder,
         MetadataBuilder;
 
-import 'kernel_shadow_ast.dart' show ShadowField;
-
 class KernelFieldBuilder extends FieldBuilder<Expression> {
-  final ShadowField field;
+  final Field field;
   final List<MetadataBuilder> metadata;
   final KernelTypeBuilder type;
   Token constInitializerToken;
 
+  bool hadTypesInferred = false;
+
   KernelFieldBuilder(this.metadata, this.type, String name, int modifiers,
       Declaration compilationUnit, int charOffset, int charEndOffset)
-      : field = new ShadowField(null, type == null,
-            fileUri: compilationUnit?.fileUri)
+      : field = new Field(null, fileUri: compilationUnit?.fileUri)
           ..fileOffset = charOffset
           ..fileEndOffset = charEndOffset,
         super(name, modifiers, compilationUnit, charOffset);
@@ -95,10 +101,6 @@
       ..hasImplicitGetter = isInstanceMember
       ..hasImplicitSetter = isInstanceMember && !isConst && !isFinal
       ..isStatic = !isInstanceMember;
-    if (isEligibleForInference && !isInstanceMember) {
-      library.loader.typeInferenceEngine
-          .recordStaticFieldInferenceCandidate(field, library);
-    }
     return field;
   }
 
@@ -130,27 +132,75 @@
 
   Field get target => field;
 
-  void prepareTopLevelInference() {
-    if (!isEligibleForInference) return;
+  @override
+  void inferType() {
     KernelLibraryBuilder library = this.library;
-    var typeInferrer = library.loader.typeInferenceEngine
-        .createTopLevelTypeInferrer(
-            field.enclosingClass?.thisType, field, null);
-    if (hasInitializer) {
-      if (field.type is! ImplicitFieldType) {
-        unsupported(
-            "$name has unexpected type ${field.type}", charOffset, fileUri);
-        return;
-      }
-      ImplicitFieldType type = field.type;
-      field.type = const DynamicType();
-      KernelBodyBuilder bodyBuilder =
-          new KernelBodyBuilder.forField(this, typeInferrer);
-      bodyBuilder.constantContext =
-          isConst ? ConstantContext.inferred : ConstantContext.none;
-      initializer = bodyBuilder.parseFieldInitializer(type.initializerToken);
-      type.initializerToken = null;
+    if (field.type is! ImplicitFieldType) {
+      // We have already inferred a type.
+      return;
     }
+    ImplicitFieldType type = field.type;
+    if (type.member != this) {
+      // The implicit type was inherited.
+      KernelFieldBuilder other = type.member;
+      other.inferCopiedType(field);
+      return;
+    }
+    if (type.isStarted) {
+      library.addProblem(
+          templateCantInferTypeDueToCircularity.withArguments(name),
+          charOffset,
+          name.length,
+          fileUri);
+      field.type = const InvalidType();
+      return;
+    }
+    type.isStarted = true;
+    TypeInferrerImpl typeInferrer = library.loader.typeInferenceEngine
+        .createTopLevelTypeInferrer(
+            fileUri, field.enclosingClass?.thisType, null);
+    KernelBodyBuilder bodyBuilder =
+        new KernelBodyBuilder.forField(this, typeInferrer);
+    bodyBuilder.constantContext =
+        isConst ? ConstantContext.inferred : ConstantContext.none;
+    initializer = bodyBuilder.parseFieldInitializer(type.initializerToken);
+    type.initializerToken = null;
+
+    DartType inferredType = typeInferrer.inferDeclarationType(typeInferrer
+        .inferExpression(field.initializer, const UnknownType(), true,
+            isVoidAllowed: true));
+
+    if (field.type is ImplicitFieldType) {
+      // `field.type` may have changed if a circularity was detected when
+      // [inferredType] was computed.
+      field.type = inferredType;
+
+      IncludesTypeParametersCovariantly needsCheckVisitor;
+      if (parent is ClassBuilder) {
+        Class enclosingClass = parent.target;
+        if (enclosingClass.typeParameters.isNotEmpty) {
+          needsCheckVisitor = new IncludesTypeParametersCovariantly(
+              enclosingClass.typeParameters);
+        }
+      }
+      if (needsCheckVisitor != null) {
+        if (field.type.accept(needsCheckVisitor)) {
+          field.isGenericCovariantImpl = true;
+        }
+      }
+    }
+
+    // The following is a hack. The outline should contain the compiled
+    // initializers, however, as top-level inference is subtly different from
+    // we need to compile the field initializer again when everything else is
+    // compiled.
+    field.initializer = null;
+  }
+
+  void inferCopiedType(Field other) {
+    inferType();
+    other.type = field.type;
+    other.initializer = null;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 91a846a..6c5e907 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -103,6 +103,8 @@
         namedMixinApplicationMask,
         staticMask;
 
+import '../names.dart' show indexSetName;
+
 import '../problems.dart' show unexpected, unhandled;
 
 import '../severity.dart' show Severity;
@@ -203,6 +205,8 @@
 
   List<KernelFormalParameterBuilder> untypedInitializingFormals;
 
+  List<KernelFieldBuilder> implicitlyTypedFields;
+
   KernelLibraryBuilder(Uri uri, Uri fileUri, Loader loader, this.actualOrigin,
       [Scope scope, Library target])
       : library = target ??
@@ -648,6 +652,7 @@
     addBuilder(name, field, charOffset);
     if (!legacyMode && type == null && initializerToken != null) {
       field.target.type = new ImplicitFieldType(field, initializerToken);
+      (implicitlyTypedFields ??= <KernelFieldBuilder>[]).add(field);
     }
     loader.target.metadataCollector
         ?.setDocumentationComment(field.target, documentationComment);
@@ -713,6 +718,14 @@
       String nativeMethodName,
       {bool isTopLevel}) {
     MetadataCollector metadataCollector = loader.target.metadataCollector;
+    if (returnType == null) {
+      if (kind == ProcedureKind.Operator &&
+          identical(name, indexSetName.name)) {
+        returnType = addVoidType(charOffset);
+      } else if (kind == ProcedureKind.Setter) {
+        returnType = addVoidType(charOffset);
+      }
+    }
     ProcedureBuilder procedure = new KernelProcedureBuilder(
         metadata,
         modifiers,
@@ -1361,9 +1374,9 @@
   }
 
   @override
-  void includePart(
+  bool includePart(
       covariant KernelLibraryBuilder part, Set<Uri> usedParts, int partOffset) {
-    super.includePart(part, usedParts, partOffset);
+    if (!super.includePart(part, usedParts, partOffset)) return false;
     nativeMethods.addAll(part.nativeMethods);
     boundlessTypeVariables.addAll(part.boundlessTypeVariables);
     // Check that the targets are different. This is not normally a problem
@@ -1372,6 +1385,16 @@
       target.problemsAsJson ??= <String>[];
       target.problemsAsJson.addAll(part.target.problemsAsJson);
     }
+    List<KernelFieldBuilder> partImplicitlyTypedFields =
+        part.takeImplicitlyTypedFields();
+    if (partImplicitlyTypedFields != null) {
+      if (implicitlyTypedFields == null) {
+        implicitlyTypedFields = partImplicitlyTypedFields;
+      } else {
+        implicitlyTypedFields.addAll(partImplicitlyTypedFields);
+      }
+    }
+    return true;
   }
 
   @override
@@ -1827,6 +1850,13 @@
     untypedInitializingFormals = null;
     return count;
   }
+
+  @override
+  List<KernelFieldBuilder> takeImplicitlyTypedFields() {
+    List<KernelFieldBuilder> result = implicitlyTypedFields;
+    implicitlyTypedFields = null;
+    return result;
+  }
 }
 
 Uri computeLibraryUri(Declaration declaration) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
index 0e9e42e..d751f8c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
@@ -30,7 +30,6 @@
         TypeParameter,
         TypeParameterType,
         VariableDeclaration,
-        VoidType,
         setParents;
 
 import 'package:kernel/type_algebra.dart' show containsTypeVariable, substitute;
@@ -74,8 +73,7 @@
         TypeVariableBuilder,
         isRedirectingGenerativeConstructorImplementation;
 
-import 'kernel_shadow_ast.dart'
-    show ShadowProcedure, VariableDeclarationJudgment;
+import 'kernel_shadow_ast.dart' show VariableDeclarationJudgment;
 
 import 'redirecting_factory_body.dart' show RedirectingFactoryBody;
 
@@ -275,7 +273,7 @@
 }
 
 class KernelProcedureBuilder extends KernelFunctionBuilder {
-  final ShadowProcedure procedure;
+  final Procedure procedure;
   final int charOpenParenOffset;
 
   AsyncMarker actualAsyncModifier = AsyncMarker.Sync;
@@ -283,6 +281,8 @@
   @override
   KernelProcedureBuilder actualOrigin;
 
+  bool hadTypesInferred = false;
+
   KernelProcedureBuilder(
       List<MetadataBuilder> metadata,
       int modifiers,
@@ -297,11 +297,11 @@
       this.charOpenParenOffset,
       int charEndOffset,
       [String nativeMethodName])
-      : procedure = new ShadowProcedure(null, kind, null, returnType == null,
-            fileUri: compilationUnit?.fileUri)
-          ..startFileOffset = startCharOffset
-          ..fileOffset = charOffset
-          ..fileEndOffset = charEndOffset,
+      : procedure =
+            new Procedure(null, kind, null, fileUri: compilationUnit?.fileUri)
+              ..startFileOffset = startCharOffset
+              ..fileOffset = charOffset
+              ..fileEndOffset = charEndOffset,
         super(metadata, modifiers, returnType, name, typeVariables, formals,
             compilationUnit, charOffset, nativeMethodName);
 
@@ -354,11 +354,6 @@
       procedure.isConst = isConst;
       procedure.name = new Name(name, library.target);
     }
-    if (!library.loader.target.legacyMode &&
-        (isSetter || (isOperator && name == '[]=')) &&
-        returnType == null) {
-      procedure.function.returnType = const VoidType();
-    }
     return procedure;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index e91b0a4..4a5bc98 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -59,10 +59,8 @@
 
 import '../type_inference/inference_helper.dart' show InferenceHelper;
 
-import '../type_inference/interface_resolver.dart' show InterfaceResolver;
-
 import '../type_inference/type_inference_engine.dart'
-    show IncludesTypeParametersCovariantly, InferenceNode, TypeInferenceEngine;
+    show IncludesTypeParametersCovariantly, TypeInferenceEngine;
 
 import '../type_inference/type_inferrer.dart'
     show ExpressionInferenceResult, TypeInferrer, TypeInferrerImpl;
@@ -280,59 +278,6 @@
   }
 }
 
-/// Shadow object representing a class in kernel form.
-class ShadowClass extends Class {
-  ClassInferenceInfo _inferenceInfo;
-
-  ShadowClass(
-      {String name,
-      Supertype supertype,
-      Supertype mixedInType,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes,
-      List<Procedure> procedures,
-      List<Field> fields})
-      : super(
-            name: name,
-            supertype: supertype,
-            mixedInType: mixedInType,
-            typeParameters: typeParameters,
-            implementedTypes: implementedTypes,
-            procedures: procedures,
-            fields: fields);
-
-  /// Resolves all forwarding nodes for this class, propagates covariance
-  /// annotations, and creates forwarding stubs as needed.
-  void finalizeCovariance(InterfaceResolver interfaceResolver) {
-    interfaceResolver.finalizeCovariance(
-        this, _inferenceInfo.gettersAndMethods, _inferenceInfo.builder.library);
-    interfaceResolver.finalizeCovariance(
-        this, _inferenceInfo.setters, _inferenceInfo.builder.library);
-  }
-
-  /// Creates API members for this class.
-  void setupApiMembers(InterfaceResolver interfaceResolver) {
-    interfaceResolver.createApiMembers(this, _inferenceInfo.gettersAndMethods,
-        _inferenceInfo.setters, _inferenceInfo.builder.library);
-  }
-
-  static void clearClassInferenceInfo(ShadowClass class_) {
-    class_._inferenceInfo = null;
-  }
-
-  static ClassInferenceInfo getClassInferenceInfo(Class class_) {
-    if (class_ is ShadowClass) return class_._inferenceInfo;
-    return null;
-  }
-
-  /// Initializes the class inference information associated with the given
-  /// [class_], starting with the fact that it is associated with the given
-  /// [builder].
-  static void setBuilder(ShadowClass class_, SourceClassBuilder builder) {
-    class_._inferenceInfo = new ClassInferenceInfo(builder);
-  }
-}
-
 /// Abstract shadow object representing a complex assignment in kernel form.
 ///
 /// Since there are many forms a complex assignment might have been desugared
@@ -635,32 +580,6 @@
   }
 }
 
-/// Concrete shadow object representing a field in kernel form.
-class ShadowField extends Field implements ShadowMember {
-  @override
-  InferenceNode inferenceNode;
-
-  ShadowTypeInferrer _typeInferrer;
-
-  final bool _isImplicitlyTyped;
-
-  ShadowField(Name name, this._isImplicitlyTyped, {Uri fileUri})
-      : super(name, fileUri: fileUri) {}
-
-  @override
-  void setInferredType(
-      TypeInferenceEngine engine, Uri uri, DartType inferredType) {
-    type = inferredType;
-  }
-
-  static bool isImplicitlyTyped(ShadowField field) => field._isImplicitlyTyped;
-
-  static void setInferenceNode(ShadowField field, InferenceNode node) {
-    assert(field.inferenceNode == null);
-    field.inferenceNode = node;
-  }
-}
-
 /// Concrete shadow object representing a field initializer in kernel form.
 class ShadowFieldInitializer extends FieldInitializer
     implements InitializerJudgment {
@@ -1000,18 +919,6 @@
   }
 }
 
-/// Abstract shadow object representing a field or procedure in kernel form.
-abstract class ShadowMember implements Member {
-  Uri get fileUri;
-
-  InferenceNode get inferenceNode;
-
-  void set inferenceNode(InferenceNode value);
-
-  void setInferredType(
-      TypeInferenceEngine engine, Uri uri, DartType inferredType);
-}
-
 /// Shadow object for [MethodInvocation].
 class MethodInvocationJudgment extends MethodInvocation
     implements ExpressionJudgment {
@@ -1110,37 +1017,6 @@
   }
 }
 
-/// Concrete shadow object representing a procedure in kernel form.
-class ShadowProcedure extends Procedure implements ShadowMember {
-  @override
-  InferenceNode inferenceNode;
-
-  final bool _hasImplicitReturnType;
-
-  ShadowProcedure(Name name, ProcedureKind kind, FunctionNode function,
-      this._hasImplicitReturnType,
-      {Uri fileUri, bool isAbstract: false})
-      : super(name, kind, function, fileUri: fileUri, isAbstract: isAbstract);
-
-  @override
-  void setInferredType(
-      TypeInferenceEngine engine, Uri uri, DartType inferredType) {
-    if (isSetter) {
-      if (function.positionalParameters.length > 0) {
-        function.positionalParameters[0].type = inferredType;
-      }
-    } else if (isGetter) {
-      function.returnType = inferredType;
-    } else {
-      unhandled("setInferredType", "not accessor", fileOffset, uri);
-    }
-  }
-
-  static bool hasImplicitReturnType(ShadowProcedure procedure) {
-    return procedure._hasImplicitReturnType;
-  }
-}
-
 /// Concrete shadow object representing an assignment to a property.
 class PropertyAssignmentJudgment extends ComplexAssignmentJudgmentWithReceiver {
   /// If this assignment uses null-aware access (`?.`), the conditional
@@ -1470,14 +1346,8 @@
 
   @override
   ShadowTypeInferrer createTopLevelTypeInferrer(
-      InterfaceType thisType, ShadowField field, KernelLibraryBuilder library) {
-    return field._typeInferrer =
-        new TypeInferrer(this, field.fileUri, true, thisType, library);
-  }
-
-  @override
-  ShadowTypeInferrer getFieldTypeInferrer(ShadowField field) {
-    return field._typeInferrer;
+      Uri uri, InterfaceType thisType, KernelLibraryBuilder library) {
+    return new TypeInferrer(this, uri, true, thisType, library);
   }
 }
 
@@ -1493,7 +1363,7 @@
         super.private(engine, uri, topLevel, thisType, library);
 
   @override
-  Expression getFieldInitializer(ShadowField field) {
+  Expression getFieldInitializer(Field field) {
     return field.initializer;
   }
 
@@ -1536,13 +1406,6 @@
   }
 
   @override
-  DartType inferFieldTopLevel(ShadowField field) {
-    if (field.initializer == null) return const DynamicType();
-    return inferExpression(field.initializer, const UnknownType(), true,
-        isVoidAllowed: true);
-  }
-
-  @override
   void inferInitializer(
       InferenceHelper helper, kernel.Initializer initializer) {
     assert(initializer is InitializerJudgment);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 5d67c40..0128ab2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -87,7 +87,6 @@
 import 'kernel_builder.dart'
     show
         ClassBuilder,
-        ClassHierarchyBuilder,
         Declaration,
         InvalidTypeBuilder,
         KernelClassBuilder,
@@ -152,8 +151,6 @@
     loader = createLoader();
   }
 
-  void set builderHierarchy(ClassHierarchyBuilder o) {}
-
   SourceLoader createLoader() =>
       new SourceLoader(fileSystem, includeComments, this);
 
@@ -268,8 +265,7 @@
       component =
           link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
       computeCoreTypes();
-      builderHierarchy =
-          loader.buildClassHierarchy(myClasses, objectClassBuilder);
+      loader.buildClassHierarchy(myClasses, objectClassBuilder);
       loader.computeHierarchy();
       loader.performTopLevelInference(myClasses);
       loader.checkSupertypes(myClasses);
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 09cd1c9..3adef89 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -41,21 +41,19 @@
         TypeVariableBuilder,
         compareProcedures;
 
-import '../kernel/kernel_shadow_ast.dart' show ShadowClass;
-
 import '../kernel/type_algorithms.dart' show Variance, computeVariance;
 
 import '../problems.dart' show unexpected, unhandled;
 
-ShadowClass initializeClass(
-    ShadowClass cls,
+Class initializeClass(
+    Class cls,
     List<TypeVariableBuilder> typeVariables,
     String name,
     KernelLibraryBuilder parent,
     int startCharOffset,
     int charOffset,
     int charEndOffset) {
-  cls ??= new ShadowClass(
+  cls ??= new Class(
       name: name,
       typeParameters:
           KernelTypeVariableBuilder.kernelTypeParametersFromBuilders(
@@ -105,12 +103,10 @@
       : actualCls = initializeClass(cls, typeVariables, name, parent,
             startCharOffset, charOffset, charEndOffset),
         super(metadata, modifiers, name, typeVariables, supertype, interfaces,
-            scope, constructors, parent, charOffset) {
-    ShadowClass.setBuilder(this.cls, this);
-  }
+            scope, constructors, parent, charOffset);
 
   @override
-  ShadowClass get cls => origin.actualCls;
+  Class get cls => origin.actualCls;
 
   @override
   KernelLibraryBuilder get library => super.library;
@@ -278,20 +274,6 @@
     constructorScopeBuilder.addMember(name, memberBuilder);
   }
 
-  void prepareTopLevelInference() {
-    scope.forEach((String name, Declaration declaration) {
-      do {
-        if (declaration is KernelFieldBuilder) {
-          declaration.prepareTopLevelInference();
-        }
-        declaration = declaration.next;
-      } while (declaration != null);
-    });
-    if (!isPatch) {
-      cls.setupApiMembers(library.loader.interfaceResolver);
-    }
-  }
-
   @override
   int finishPatch() {
     if (!isPatch) return 0;
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 89abbb2..6fba08ef 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -703,7 +703,7 @@
     }
   }
 
-  void includePart(
+  bool includePart(
       SourceLibraryBuilder<T, R> part, Set<Uri> usedParts, int partOffset) {
     if (part.partOfUri != null) {
       if (uriIsValid(part.partOfUri) && part.partOfUri != uri) {
@@ -715,7 +715,7 @@
             partOffset,
             noLength,
             fileUri);
-        return;
+        return false;
       }
     } else if (part.partOfName != null) {
       if (name != null) {
@@ -728,7 +728,7 @@
               partOffset,
               noLength,
               fileUri);
-          return;
+          return false;
         }
       } else {
         // This is an error, but the part is not removed from the list of parts,
@@ -739,7 +739,7 @@
             partOffset,
             noLength,
             fileUri);
-        return;
+        return false;
       }
     } else {
       // This is an error, but the part is not removed from the list of parts,
@@ -749,7 +749,7 @@
         addProblem(templateMissingPartOf.withArguments(part.fileUri),
             partOffset, noLength, fileUri);
       }
-      return;
+      return false;
     }
     part.validatePart(this, usedParts);
     NameIterator partDeclarations = part.nameIterator;
@@ -798,6 +798,7 @@
     part.partOfLibrary = this;
     part.scope.becomePartOf(scope);
     // TODO(ahe): Include metadata from part?
+    return true;
   }
 
   void buildInitialScopes() {
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 3040e27..74fcaa1 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -68,17 +68,18 @@
         templateSourceOutlineSummary,
         templateUntranslatableUri;
 
-import '../kernel/kernel_shadow_ast.dart'
-    show ShadowClass, ShadowTypeInferenceEngine;
+import '../kernel/kernel_shadow_ast.dart' show ShadowTypeInferenceEngine;
 
 import '../kernel/kernel_builder.dart'
     show
         ClassBuilder,
         ClassHierarchyBuilder,
         Declaration,
+        DelayedMember,
+        DelayedOverrideCheck,
         EnumBuilder,
+        FieldBuilder,
         KernelClassBuilder,
-        KernelFieldBuilder,
         KernelProcedureBuilder,
         KernelTypeBuilder,
         LibraryBuilder,
@@ -107,8 +108,6 @@
 import '../scanner.dart'
     show ErrorToken, ScannerConfiguration, ScannerResult, Token, scan;
 
-import '../type_inference/interface_resolver.dart' show InterfaceResolver;
-
 import 'diet_listener.dart' show DietListener;
 
 import 'diet_parser.dart' show DietParser;
@@ -128,6 +127,8 @@
 
   final Map<Uri, List<int>> sourceBytes = <Uri, List<int>>{};
 
+  ClassHierarchyBuilder builderHierarchy;
+
   // Used when building directly to kernel.
   ClassHierarchy hierarchy;
   CoreTypes coreTypes;
@@ -138,8 +139,6 @@
 
   ShadowTypeInferenceEngine typeInferenceEngine;
 
-  InterfaceResolver interfaceResolver;
-
   Instrumentation instrumentation;
 
   CollectionTransformer collectionTransformer;
@@ -609,6 +608,10 @@
             break;
           }
         }
+        if (allSupertypesProcessed && cls.isPatch) {
+          allSupertypesProcessed =
+              topologicallySortedClasses.contains(cls.origin);
+        }
         if (allSupertypesProcessed) {
           topologicallySortedClasses.add(cls);
           checkClassSupertypes(cls, directSupertypes, blackListedClasses);
@@ -884,27 +887,33 @@
   }
 
   void checkOverrides(List<SourceClassBuilder> sourceClasses) {
-    assert(hierarchy != null);
-    for (SourceClassBuilder builder in sourceClasses) {
-      if (builder.library.loader == this && !builder.isPatch) {
-        builder.checkOverrides(
-            hierarchy, typeInferenceEngine?.typeSchemaEnvironment);
-      }
+    List<DelayedOverrideCheck> overrideChecks =
+        builderHierarchy.overrideChecks.toList();
+    builderHierarchy.overrideChecks.clear();
+    for (int i = 0; i < overrideChecks.length; i++) {
+      overrideChecks[i].check(builderHierarchy);
     }
-    ticker.logMs("Checked overrides");
+    ticker.logMs("Checked ${overrideChecks.length} overrides");
+
+    typeInferenceEngine?.finishTopLevelInitializingFormals();
+    ticker.logMs("Finished initializing formals");
   }
 
   void checkAbstractMembers(List<SourceClassBuilder> sourceClasses) {
-    // TODO(ahe): Move this to [ClassHierarchyBuilder].
-    if (target.legacyMode) return;
-    assert(hierarchy != null);
-    for (SourceClassBuilder builder in sourceClasses) {
-      if (builder.library.loader == this && !builder.isPatch) {
-        builder.checkAbstractMembers(
-            coreTypes, hierarchy, typeInferenceEngine.typeSchemaEnvironment);
-      }
+    List<DelayedMember> delayedMemberChecks =
+        builderHierarchy.delayedMemberChecks.toList();
+    builderHierarchy.delayedMemberChecks.clear();
+    Set<Class> changedClasses = new Set<Class>();
+    for (int i = 0; i < delayedMemberChecks.length; i++) {
+      delayedMemberChecks[i].check(builderHierarchy);
+      changedClasses.add(delayedMemberChecks[i].parent.cls);
     }
-    ticker.logMs("Checked abstract members");
+    ticker.logMs(
+        "Computed ${delayedMemberChecks.length} combined member signatures");
+
+    hierarchy.applyMemberChanges(changedClasses, findDescendants: false);
+    ticker
+        .logMs("Updated ${changedClasses.length} classes in kernel hierarchy");
   }
 
   void checkRedirectingFactories(List<SourceClassBuilder> sourceClasses) {
@@ -968,12 +977,12 @@
     });
   }
 
-  ClassHierarchyBuilder buildClassHierarchy(
+  void buildClassHierarchy(
       List<SourceClassBuilder> sourceClasses, ClassBuilder objectClass) {
-    ClassHierarchyBuilder hierarchy = ClassHierarchyBuilder.build(
+    builderHierarchy = ClassHierarchyBuilder.build(
         objectClass, sourceClasses, this, coreTypes);
+    typeInferenceEngine?.hierarchyBuilder = builderHierarchy;
     ticker.logMs("Built class hierarchy");
-    return hierarchy;
   }
 
   void createTypeInferenceEngine() {
@@ -989,58 +998,30 @@
     /// might be subject to type inference, and records dependencies between
     /// them.
     typeInferenceEngine.prepareTopLevel(coreTypes, hierarchy);
-    interfaceResolver = new InterfaceResolver(typeInferenceEngine,
-        typeInferenceEngine.typeSchemaEnvironment, instrumentation);
+    List<FieldBuilder> allImplicitlyTypedFields = <FieldBuilder>[];
     for (LibraryBuilder library in builders.values) {
       if (library.loader == this) {
-        Iterator<Declaration> iterator = library.iterator;
-        while (iterator.moveNext()) {
-          Declaration member = iterator.current;
-          if (member is KernelFieldBuilder) {
-            member.prepareTopLevelInference();
-          }
+        List<FieldBuilder> implicitlyTypedFields =
+            library.takeImplicitlyTypedFields();
+        if (implicitlyTypedFields != null) {
+          allImplicitlyTypedFields.addAll(implicitlyTypedFields);
         }
       }
     }
-    for (int i = 0; i < sourceClasses.length; i++) {
-      sourceClasses[i].prepareTopLevelInference();
+
+    for (int i = 0; i < allImplicitlyTypedFields.length; i++) {
+      // TODO(ahe): This can cause a crash for parts that failed to get
+      // included, see for example,
+      // tests/standalone_2/io/http_cookie_date_test.dart.
+      allImplicitlyTypedFields[i].inferType();
     }
+
     typeInferenceEngine.isTypeInferencePrepared = true;
-    ticker.logMs("Prepared top level inference");
 
-    /// The second phase of top level initializer inference, which is to visit
-    /// fields and top level variables in topologically-sorted order and assign
-    /// their types.
-    typeInferenceEngine.finishTopLevelFields();
-    List<Class> changedClasses = new List<Class>();
-    for (var builder in sourceClasses) {
-      if (builder.isPatch) continue;
-      ShadowClass class_ = builder.target;
-      int memberCount = class_.fields.length +
-          class_.constructors.length +
-          class_.procedures.length +
-          class_.redirectingFactoryConstructors.length;
-      class_.finalizeCovariance(interfaceResolver);
-      ShadowClass.clearClassInferenceInfo(class_);
-      int newMemberCount = class_.fields.length +
-          class_.constructors.length +
-          class_.procedures.length +
-          class_.redirectingFactoryConstructors.length;
-      if (newMemberCount != memberCount) {
-        // The inference potentially adds new members (but doesn't otherwise
-        // change the classes), so if the member count has changed we need to
-        // update the class in the class hierarchy.
-        changedClasses.add(class_);
-      }
-    }
-
-    typeInferenceEngine.finishTopLevelInitializingFormals();
-    interfaceResolver = null;
     // Since finalization of covariance may have added forwarding stubs, we need
     // to recompute the class hierarchy so that method compilation will properly
     // target those forwarding stubs.
     hierarchy.onAmbiguousSupertypes = ignoreAmbiguousSupertypes;
-    hierarchy.applyMemberChanges(changedClasses, findDescendants: true);
     ticker.logMs("Performed top level inference");
   }
 
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
deleted file mode 100644
index 5c8dbfa..0000000
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ /dev/null
@@ -1,1235 +0,0 @@
-// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-import 'package:kernel/ast.dart'
-    show
-        Arguments,
-        Class,
-        DartType,
-        DynamicType,
-        Expression,
-        Field,
-        FunctionNode,
-        FunctionType,
-        InvalidType,
-        Member,
-        Name,
-        NamedExpression,
-        Procedure,
-        ProcedureKind,
-        ReturnStatement,
-        SuperMethodInvocation,
-        SuperPropertyGet,
-        SuperPropertySet,
-        TypeParameter,
-        TypeParameterType,
-        VariableDeclaration,
-        VariableGet,
-        VoidType;
-
-import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
-
-import 'package:kernel/transformations/flags.dart' show TransformerFlag;
-
-import 'package:kernel/type_algebra.dart' show Substitution;
-
-import 'package:kernel/src/hierarchy_based_type_environment.dart'
-    show HierarchyBasedTypeEnvironment;
-
-import '../../base/instrumentation.dart'
-    show Instrumentation, InstrumentationValueLiteral;
-
-import '../builder/builder.dart' show LibraryBuilder;
-
-import '../kernel/kernel_library_builder.dart' show KernelLibraryBuilder;
-
-import '../kernel/kernel_shadow_ast.dart'
-    show ShadowClass, ShadowField, ShadowProcedure, VariableDeclarationJudgment;
-
-import '../messages.dart'
-    show
-        noLength,
-        templateCantInferTypeDueToCircularity,
-        templateCantInferTypeDueToInconsistentOverrides;
-
-import '../names.dart' show indexSetName;
-
-import '../problems.dart' show unhandled;
-
-import 'type_inference_engine.dart'
-    show
-        FieldInitializerInferenceNode,
-        IncludesTypeParametersCovariantly,
-        InferenceNode,
-        TypeInferenceEngine;
-
-import 'type_inferrer.dart' show getNamedFormal;
-
-import 'type_schema_environment.dart'
-    show
-        getNamedParameterType,
-        getPositionalParameterType,
-        substituteTypeParams;
-
-/// Concrete class derived from [InferenceNode] to represent type inference of
-/// getters, setters, and fields based on inheritance.
-class AccessorInferenceNode extends InferenceNode {
-  final InterfaceResolver _interfaceResolver;
-
-  /// The method whose return type and/or parameter types should be inferred.
-  final Procedure _declaredMethod;
-
-  /// A list containing the methods overridden by [_declaredMethod], if any.
-  final List<Member> _candidates;
-
-  /// The index of the first method in [_candidates] overridden by
-  /// [_declaredMethod].
-  final int _start;
-
-  /// The past-the-end index of the last method in [_candidates] overridden by
-  /// [_declaredMethod].
-  final int _end;
-
-  final LibraryBuilder _library;
-
-  final Uri _fileUri;
-
-  AccessorInferenceNode(this._interfaceResolver, this._declaredMethod,
-      this._candidates, this._start, this._end, this._library, this._fileUri);
-
-  String get _name {
-    if (_declaredMethod is! SyntheticAccessor && _declaredMethod.isSetter) {
-      return _declaredMethod.function.positionalParameters[0].name;
-    }
-    return _declaredMethod.name.name;
-  }
-
-  int get _offset {
-    if (_declaredMethod is! SyntheticAccessor && _declaredMethod.isSetter) {
-      return _declaredMethod.function.positionalParameters[0].fileOffset;
-    }
-    return _declaredMethod.fileOffset;
-  }
-
-  @override
-  void resolveInternal() {
-    var declaredMethod = _declaredMethod;
-    var kind = declaredMethod.kind;
-    var overriddenTypes = _computeAccessorOverriddenTypes();
-    DartType inferredType;
-    if (isCircular) {
-      inferredType = const InvalidType();
-      _library.addProblem(
-          templateCantInferTypeDueToCircularity.withArguments(_name),
-          _offset,
-          noLength,
-          _fileUri);
-    } else {
-      inferredType = _interfaceResolver.matchTypes(
-          overriddenTypes, _library, _name, _fileUri, _offset);
-    }
-    if (declaredMethod is SyntheticAccessor) {
-      declaredMethod._field.type = inferredType;
-      declaredMethod._field.initializer = null;
-    } else {
-      if (kind == ProcedureKind.Getter) {
-        declaredMethod.function.returnType = inferredType;
-      } else {
-        declaredMethod.function.positionalParameters[0].type = inferredType;
-      }
-    }
-  }
-
-  /// Computes the types of the getters and setters overridden by
-  /// [_declaredMethod], with appropriate type parameter substitutions.
-  List<DartType> _computeAccessorOverriddenTypes() {
-    var overriddenTypes = <DartType>[];
-    for (int i = _start; i < _end; i++) {
-      var candidate = _candidates[i];
-      Procedure resolvedCandidate;
-      if (candidate is ForwardingNode) {
-        resolvedCandidate = candidate.resolve();
-      } else {
-        resolvedCandidate = candidate;
-      }
-      DartType overriddenType;
-      if (resolvedCandidate is SyntheticAccessor) {
-        var field = resolvedCandidate._field;
-        TypeInferenceEngine.resolveInferenceNode(field);
-        overriddenType = field.type;
-      } else if (resolvedCandidate.function != null) {
-        switch (resolvedCandidate.kind) {
-          case ProcedureKind.Getter:
-            overriddenType = resolvedCandidate.function.returnType;
-            break;
-          case ProcedureKind.Setter:
-            overriddenType =
-                resolvedCandidate.function.positionalParameters[0].type;
-            break;
-          default:
-            // Illegal override (error will be reported elsewhere).  Just skip
-            // this override.
-            continue;
-        }
-      } else {
-        // This can happen if there are errors.  Just skip this override.
-        continue;
-      }
-      overriddenTypes.add(_interfaceResolver
-          ._substitutionFor(resolvedCandidate, _declaredMethod.enclosingClass)
-          .substituteType(overriddenType));
-    }
-    return overriddenTypes;
-  }
-}
-
-/// A [ForwardingNode] represents a method, getter, or setter within a class's
-/// interface that is either implemented in the class directly or inherited from
-/// a superclass.
-///
-/// This class allows us to defer the determination of exactly which member is
-/// inherited, as well as the propagation of covariance annotations, and
-/// the creation of forwarding stubs, until type inference.
-class ForwardingNode extends Procedure {
-  /// The [InterfaceResolver] that created this [ForwardingNode].
-  final InterfaceResolver _interfaceResolver;
-
-  /// A list containing the directly implemented and directly inherited
-  /// procedures of the class in question.
-  ///
-  /// Note that many [ForwardingNode]s share the same [_candidates] list;
-  /// consult [_start] and [_end] to see which entries in this list are relevant
-  /// to this [ForwardingNode].
-  final List<Member> _candidates;
-
-  /// Index of the first entry in [_candidates] relevant to this
-  /// [ForwardingNode].
-  final int _start;
-
-  /// Index just beyond the last entry in [_candidates] relevant to this
-  /// [ForwardingNode].
-  final int _end;
-
-  /// The member this node resolves to (if it has been computed); otherwise
-  /// `null`.
-  Member _resolution;
-
-  /// The result of finalizing this node (if the node has been finalized);
-  /// otherwise `null`.
-  Member _finalResolution;
-
-  /// If this forwarding node represents a member that needs type inference, the
-  /// corresponding [InferenceNode]; otherwise `null`.
-  InferenceNode _inferenceNode;
-
-  ForwardingNode(this._interfaceResolver, this._inferenceNode, Class class_,
-      Name name, ProcedureKind kind, this._candidates, this._start, this._end)
-      : super(name, kind, null) {
-    parent = class_;
-  }
-
-  /// Finishes handling of this node by propagating covariance and creating
-  /// forwarding stubs if necessary.
-  Procedure finalize() => _finalResolution ??= _finalize();
-
-  /// Returns the declared or inherited member this node resolves to.
-  ///
-  /// Does not create forwarding stubs.
-  Procedure resolve() => _resolution ??= _resolve();
-
-  /// Tag the parameters of [interfaceMember] that need type checks
-  ///
-  /// Parameters can need type checks for calls coming from statically typed
-  /// call sites, due to covariant generics and overrides with explicit
-  /// `covariant` parameters.
-  ///
-  /// Tag parameters of [interfaceMember] that need such checks when the member
-  /// occurs in [enclosingClass]'s interface.  If parameters need checks but
-  /// they would not be checked in an inherited implementation, a forwarding
-  /// stub is introduced as a place to put the checks.
-  Procedure _computeCovarianceFixes(Procedure interfaceMember) {
-    var substitution =
-        _interfaceResolver._substitutionFor(interfaceMember, enclosingClass);
-    // We always create a forwarding stub when we've inherited a member from an
-    // interface other than the first override candidate.  This is to work
-    // around a bug in the Kernel type checker where it chooses the first
-    // override candidate.
-    //
-    // TODO(kmillikin): Fix the Kernel type checker and stop creating these
-    // extra stubs.
-    var stub = interfaceMember.enclosingClass == enclosingClass ||
-            interfaceMember == _resolvedCandidate(_start)
-        ? interfaceMember
-        : _createForwardingStub(substitution, interfaceMember);
-
-    var interfaceFunction = interfaceMember.function;
-    var interfacePositionalParameters = interfaceFunction.positionalParameters;
-    var interfaceNamedParameters = interfaceFunction.namedParameters;
-    var interfaceTypeParameters = interfaceFunction.typeParameters;
-
-    void createStubIfNeeded() {
-      if (stub != interfaceMember) return;
-      if (interfaceMember.enclosingClass == enclosingClass) return;
-      stub = _createForwardingStub(substitution, interfaceMember);
-    }
-
-    bool isImplCreated = false;
-    void createImplIfNeeded() {
-      if (isImplCreated) return;
-      createStubIfNeeded();
-      _createForwardingImplIfNeeded(stub.function);
-      isImplCreated = true;
-    }
-
-    IncludesTypeParametersCovariantly needsCheckVisitor =
-        enclosingClass.typeParameters.isEmpty
-            ? null
-            : ShadowClass.getClassInferenceInfo(enclosingClass)
-                    .needsCheckVisitor ??=
-                new IncludesTypeParametersCovariantly(
-                    enclosingClass.typeParameters);
-    bool needsCheck(DartType type) => needsCheckVisitor == null
-        ? false
-        : substitution.substituteType(type).accept(needsCheckVisitor);
-    for (int i = 0; i < interfacePositionalParameters.length; i++) {
-      var parameter = interfacePositionalParameters[i];
-      var isGenericCovariantImpl =
-          parameter.isGenericCovariantImpl || needsCheck(parameter.type);
-      var isCovariant = parameter.isCovariant;
-      var superParameter = parameter;
-      for (int j = _start; j < _end; j++) {
-        var otherMember = _finalizedCandidate(j);
-        if (otherMember is ForwardingNode) continue;
-        var otherPositionalParameters =
-            otherMember.function.positionalParameters;
-        if (otherPositionalParameters.length <= i) continue;
-        var otherParameter = otherPositionalParameters[i];
-        if (j == _start) superParameter = otherParameter;
-        if (identical(otherMember, interfaceMember)) continue;
-        if (otherParameter.isGenericCovariantImpl) {
-          isGenericCovariantImpl = true;
-        }
-        if (otherParameter.isCovariant) {
-          isCovariant = true;
-        }
-      }
-      if (isGenericCovariantImpl) {
-        if (!superParameter.isGenericCovariantImpl) {
-          createImplIfNeeded();
-        }
-        if (!parameter.isGenericCovariantImpl) {
-          createStubIfNeeded();
-          stub.function.positionalParameters[i].isGenericCovariantImpl = true;
-        }
-      }
-      if (isCovariant) {
-        if (!superParameter.isCovariant) {
-          createImplIfNeeded();
-        }
-        if (!parameter.isCovariant) {
-          createStubIfNeeded();
-          stub.function.positionalParameters[i].isCovariant = true;
-        }
-      }
-    }
-    for (int i = 0; i < interfaceNamedParameters.length; i++) {
-      var parameter = interfaceNamedParameters[i];
-      var isGenericCovariantImpl =
-          parameter.isGenericCovariantImpl || needsCheck(parameter.type);
-      var isCovariant = parameter.isCovariant;
-      var superParameter = parameter;
-      for (int j = _start; j < _end; j++) {
-        var otherMember = _finalizedCandidate(j);
-        if (otherMember is ForwardingNode) continue;
-        var otherParameter =
-            getNamedFormal(otherMember.function, parameter.name);
-        if (otherParameter == null) continue;
-        if (j == _start) superParameter = otherParameter;
-        if (identical(otherMember, interfaceMember)) continue;
-        if (otherParameter.isGenericCovariantImpl) {
-          isGenericCovariantImpl = true;
-        }
-        if (otherParameter.isCovariant) {
-          isCovariant = true;
-        }
-      }
-      if (isGenericCovariantImpl) {
-        if (!superParameter.isGenericCovariantImpl) {
-          createImplIfNeeded();
-        }
-        if (!parameter.isGenericCovariantImpl) {
-          createStubIfNeeded();
-          stub.function.namedParameters[i].isGenericCovariantImpl = true;
-        }
-      }
-      if (isCovariant) {
-        if (!superParameter.isCovariant) {
-          createImplIfNeeded();
-        }
-        if (!parameter.isCovariant) {
-          createStubIfNeeded();
-          stub.function.namedParameters[i].isCovariant = true;
-        }
-      }
-    }
-    for (int i = 0; i < interfaceTypeParameters.length; i++) {
-      var typeParameter = interfaceTypeParameters[i];
-      var isGenericCovariantImpl = typeParameter.isGenericCovariantImpl;
-      var superTypeParameter = typeParameter;
-      for (int j = _start; j < _end; j++) {
-        var otherMember = _finalizedCandidate(j);
-        if (otherMember is ForwardingNode) continue;
-        var otherTypeParameters = otherMember.function.typeParameters;
-        if (otherTypeParameters.length <= i) continue;
-        var otherTypeParameter = otherTypeParameters[i];
-        if (j == _start) superTypeParameter = otherTypeParameter;
-        if (identical(otherMember, interfaceMember)) continue;
-        if (otherTypeParameter.isGenericCovariantImpl) {
-          isGenericCovariantImpl = true;
-        }
-      }
-      if (isGenericCovariantImpl) {
-        if (!superTypeParameter.isGenericCovariantImpl) {
-          createImplIfNeeded();
-        }
-        if (!typeParameter.isGenericCovariantImpl) {
-          createStubIfNeeded();
-          stub.function.typeParameters[i].isGenericCovariantImpl = true;
-        }
-      }
-    }
-    return stub;
-  }
-
-  void _createForwardingImplIfNeeded(FunctionNode function) {
-    if (function.body != null) {
-      // There is already an implementation; nothing further needs to be done.
-      return;
-    }
-    // Find the concrete implementation in the superclass; this is what we need
-    // to forward to.  If we can't find one, then the method is fully abstract
-    // and we don't need to do anything.
-    var superclass = enclosingClass.superclass;
-    if (superclass == null) return;
-    Procedure procedure = function.parent;
-    var superTarget = _interfaceResolver._typeEnvironment.hierarchy
-        .getDispatchTarget(superclass, procedure.name,
-            setter: kind == ProcedureKind.Setter);
-    if (superTarget == null) return;
-    if (superTarget is Procedure && superTarget.isForwardingStub) {
-      superTarget = _getForwardingStubSuperTarget(superTarget);
-    }
-    procedure.isAbstract = false;
-    if (!procedure.isForwardingStub) {
-      // This procedure exists abstractly in the source code; we need to make it
-      // concrete and give it a body that is a forwarding stub.  This situation
-      // is called a "forwarding semi-stub".
-      procedure.isForwardingStub = true;
-      procedure.isForwardingSemiStub = true;
-      _interfaceResolver._instrumentation?.record(
-          procedure.fileUri,
-          procedure.fileOffset,
-          'forwardingStub',
-          new InstrumentationValueLiteral('semi-stub'));
-    }
-    var positionalArguments = function.positionalParameters
-        .map<Expression>((parameter) => new VariableGet(parameter))
-        .toList();
-    var namedArguments = function.namedParameters
-        .map((parameter) =>
-            new NamedExpression(parameter.name, new VariableGet(parameter)))
-        .toList();
-    var typeArguments = function.typeParameters
-        .map<DartType>((typeParameter) => new TypeParameterType(typeParameter))
-        .toList();
-    var arguments = new Arguments(positionalArguments,
-        types: typeArguments, named: namedArguments);
-    Expression superCall;
-    switch (kind) {
-      case ProcedureKind.Method:
-      case ProcedureKind.Operator:
-        superCall = new SuperMethodInvocation(name, arguments, superTarget);
-        break;
-      case ProcedureKind.Getter:
-        superCall = new SuperPropertyGet(
-            name,
-            superTarget is SyntheticAccessor
-                ? superTarget._field
-                : superTarget);
-        break;
-      case ProcedureKind.Setter:
-        superCall = new SuperPropertySet(
-            name,
-            positionalArguments[0],
-            superTarget is SyntheticAccessor
-                ? superTarget._field
-                : superTarget);
-        break;
-      default:
-        unhandled('$kind', '_createForwardingImplIfNeeded', -1, null);
-        break;
-    }
-    function.body = new ReturnStatement(superCall)..parent = function;
-    procedure.transformerFlags |= TransformerFlag.superCalls;
-    procedure.forwardingStubSuperTarget = superTarget;
-  }
-
-  /// Creates a forwarding stub based on the given [target].
-  Procedure _createForwardingStub(Substitution substitution, Procedure target) {
-    VariableDeclaration copyParameter(VariableDeclaration parameter) {
-      return new VariableDeclaration(parameter.name,
-          type: substitution.substituteType(parameter.type),
-          isCovariant: parameter.isCovariant)
-        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl;
-    }
-
-    var targetTypeParameters = target.function.typeParameters;
-    List<TypeParameter> typeParameters;
-    if (targetTypeParameters.isNotEmpty) {
-      typeParameters =
-          new List<TypeParameter>.filled(targetTypeParameters.length, null);
-      var additionalSubstitution = <TypeParameter, DartType>{};
-      for (int i = 0; i < targetTypeParameters.length; i++) {
-        var targetTypeParameter = targetTypeParameters[i];
-        var typeParameter = new TypeParameter(targetTypeParameter.name, null)
-          ..isGenericCovariantImpl = targetTypeParameter.isGenericCovariantImpl;
-        typeParameters[i] = typeParameter;
-        additionalSubstitution[targetTypeParameter] =
-            new TypeParameterType(typeParameter);
-      }
-      substitution = Substitution.combine(
-          substitution, Substitution.fromMap(additionalSubstitution));
-      for (int i = 0; i < typeParameters.length; i++) {
-        typeParameters[i].bound =
-            substitution.substituteType(targetTypeParameters[i].bound);
-      }
-    }
-    var positionalParameters =
-        target.function.positionalParameters.map(copyParameter).toList();
-    var namedParameters =
-        target.function.namedParameters.map(copyParameter).toList();
-    var function = new FunctionNode(null,
-        positionalParameters: positionalParameters,
-        namedParameters: namedParameters,
-        typeParameters: typeParameters,
-        requiredParameterCount: target.function.requiredParameterCount,
-        returnType: substitution.substituteType(target.function.returnType));
-    Member finalTarget;
-    if (target is Procedure && target.isForwardingStub) {
-      finalTarget = target.forwardingStubInterfaceTarget;
-    } else if (target is SyntheticAccessor) {
-      finalTarget = target._field;
-    } else {
-      finalTarget = target;
-    }
-    return new Procedure(name, kind, function,
-        isAbstract: true,
-        isForwardingStub: true,
-        fileUri: enclosingClass.fileUri,
-        forwardingStubInterfaceTarget: finalTarget)
-      ..startFileOffset = enclosingClass.fileOffset
-      ..fileOffset = enclosingClass.fileOffset
-      ..parent = enclosingClass;
-  }
-
-  /// Creates a forwarding stub for this node if necessary, and propagates
-  /// covariance information.
-  Procedure _finalize() {
-    return _computeCovarianceFixes(resolve());
-  }
-
-  /// Returns the [i]th element of [_candidates], finalizing it if necessary.
-  Procedure _finalizedCandidate(int i) {
-    Procedure candidate = _candidates[i];
-    return candidate is ForwardingNode &&
-            _interfaceResolver.isTypeInferencePrepared
-        ? candidate.finalize()
-        : candidate;
-  }
-
-  /// Determines which inherited member this node resolves to, and also performs
-  /// type inference.
-  Procedure _resolve() {
-    Procedure inheritedMember = _candidates[_start];
-    bool isDeclaredInThisClass =
-        identical(inheritedMember.enclosingClass, enclosingClass);
-    if (isDeclaredInThisClass) {
-      if (_inferenceNode != null) {
-        _inferenceNode.resolve();
-        _inferenceNode = null;
-      }
-    } else {
-      // If there are multiple inheritance candidates, the inherited member is
-      // the member whose type is a subtype of all the others.  We can find it
-      // by two passes over the list of members.  For the first pass, we step
-      // through the candidates, updating inheritedMember each time we find a
-      // member whose type is a subtype of the previous inheritedMember.  As we
-      // do this, we also work out the necessary substitution for matching up
-      // type parameters between this class and the corresponding superclass.
-      //
-      // Since the subtyping relation is reflexive, we will favor the most
-      // recently visited candidate in the case where the types are the same.
-      // We want to favor earlier candidates, so we visit the candidate list
-      // backwards.
-      inheritedMember = _resolvedCandidate(_end - 1);
-      var inheritedMemberSubstitution =
-          _interfaceResolver._substitutionFor(inheritedMember, enclosingClass);
-      var inheritedMemberType = inheritedMember is ForwardingNode
-          ? const DynamicType()
-          : inheritedMemberSubstitution.substituteType(
-              kind == ProcedureKind.Setter
-                  ? inheritedMember.setterType
-                  : inheritedMember.getterType);
-      for (int i = _end - 2; i >= _start; i--) {
-        var candidate = _resolvedCandidate(i);
-        var substitution =
-            _interfaceResolver._substitutionFor(candidate, enclosingClass);
-        bool isBetter;
-        DartType type;
-        if (kind == ProcedureKind.Setter) {
-          type = candidate is ForwardingNode
-              ? const DynamicType()
-              : substitution.substituteType(candidate.setterType);
-          // Setters are contravariant in their setter type, so we have to
-          // reverse the check.
-          isBetter = _interfaceResolver._typeEnvironment
-              .isSubtypeOf(inheritedMemberType, type);
-        } else {
-          type = candidate is ForwardingNode
-              ? const DynamicType()
-              : substitution.substituteType(candidate.getterType);
-          isBetter = _interfaceResolver._typeEnvironment
-              .isSubtypeOf(type, inheritedMemberType);
-        }
-        if (isBetter) {
-          inheritedMember = candidate;
-          inheritedMemberSubstitution = substitution;
-          inheritedMemberType = type;
-        }
-      }
-      // For the second pass, we verify that inheritedMember is a subtype of all
-      // the other potentially inherited members.
-      // TODO(paulberry): implement this.
-    }
-    return inheritedMember;
-  }
-
-  /// Returns the [i]th element of [_candidates], resolving it if necessary.
-  Procedure _resolvedCandidate(int i) {
-    Procedure candidate = _candidates[i];
-    return candidate is ForwardingNode &&
-            _interfaceResolver.isTypeInferencePrepared
-        ? candidate.resolve()
-        : candidate;
-  }
-
-  static void createForwardingImplIfNeededForTesting(
-      ForwardingNode node, FunctionNode function) {
-    node._createForwardingImplIfNeeded(function);
-  }
-
-  /// Public method allowing tests to access [_createForwardingStub].
-  ///
-  /// This method is static so that it can be easily eliminated by tree shaking
-  /// when not needed.
-  static Procedure createForwardingStubForTesting(
-      ForwardingNode node, Substitution substitution, Procedure target) {
-    return node._createForwardingStub(substitution, target);
-  }
-
-  /// For testing: get the list of candidates relevant to a given node.
-  static List<Procedure> getCandidates(ForwardingNode node) {
-    return node._candidates.sublist(node._start, node._end);
-  }
-
-  static Member _getForwardingStubSuperTarget(Procedure forwardingStub) {
-    // TODO(paulberry): when dartbug.com/31562 is fixed, this should become
-    // easier.
-    ReturnStatement body = forwardingStub.function.body;
-    var expression = body.expression;
-    if (expression is SuperMethodInvocation) {
-      return expression.interfaceTarget;
-    } else if (expression is SuperPropertySet) {
-      return expression.interfaceTarget;
-    } else {
-      return unhandled('${expression.runtimeType}',
-          '_getForwardingStubSuperTarget', -1, null);
-    }
-  }
-}
-
-/// An [InterfaceResolver] keeps track of the information necessary to resolve
-/// method calls, gets, and sets within a chunk of code being compiled, to
-/// infer covariance annotations, and to create forwarwding stubs when necessary
-/// to meet covariance requirements.
-class InterfaceResolver {
-  final TypeInferenceEngine _typeInferenceEngine;
-
-  final HierarchyBasedTypeEnvironment _typeEnvironment;
-
-  final Instrumentation _instrumentation;
-
-  InterfaceResolver(
-      this._typeInferenceEngine, this._typeEnvironment, this._instrumentation);
-
-  /// Indicates whether the "prepare" phase of type inference is complete.
-  bool get isTypeInferencePrepared =>
-      _typeInferenceEngine.isTypeInferencePrepared;
-
-  /// Report an error if all types in [types] are not equal using `==`.
-  ///
-  /// Returns the type if there is at least one and they are all equal,
-  /// otherwise the type `dynamic`.  [library], [name], [fileUri], and
-  /// [charOffset] are used to report the error.
-  DartType matchTypes(Iterable<DartType> types, LibraryBuilder library,
-      String name, Uri fileUri, int charOffset) {
-    DartType first;
-    for (var type in types) {
-      if (first == null) {
-        first = type;
-      } else if (first != type) {
-        // Types don't match.  Report an error.
-        library.addProblem(
-            templateCantInferTypeDueToInconsistentOverrides.withArguments(name),
-            charOffset,
-            noLength,
-            fileUri);
-        return const DynamicType();
-      }
-    }
-    // If there are no overridden types, infer `dynamic`.
-    return first ?? const DynamicType();
-  }
-
-  /// Computes the types of the methods overridden by [method] in [class_].
-  ///
-  /// The types have the type parameters of [class_] substituted appropriately.
-  ///
-  /// [candidates] has the list of inherited interface methods with the same
-  /// name as [method] as a sublist from [start] inclusive to [end] exclusive.
-  List<FunctionType> _computeMethodOverriddenTypes(Class class_,
-      Procedure method, List<Member> candidates, int start, int end) {
-    var overriddenTypes = <FunctionType>[];
-    var declaredTypeParameters = method.function.typeParameters;
-    for (int i = start; i < end; ++i) {
-      var candidate = candidates[i];
-      if (candidate is SyntheticAccessor) {
-        // This can happen if there are errors.  Just skip this override.
-        continue;
-      }
-      var candidateFunction = candidate.function;
-      if (candidateFunction == null) {
-        // This can happen if there are errors.  Just skip this override.
-        continue;
-      }
-      var substitution = _substitutionFor(candidate, class_);
-      FunctionType overriddenType =
-          substitution.substituteType(candidateFunction.functionType);
-      var overriddenTypeParameters = overriddenType.typeParameters;
-      if (overriddenTypeParameters.length != declaredTypeParameters.length) {
-        // Generic arity mismatch.  Don't do any inference for this method.
-        // TODO(paulberry): report an error.
-        overriddenTypes.clear();
-        break;
-      } else if (overriddenTypeParameters.isNotEmpty) {
-        var substitutionMap = <TypeParameter, DartType>{};
-        for (int i = 0; i < declaredTypeParameters.length; ++i) {
-          substitutionMap[overriddenTypeParameters[i]] =
-              new TypeParameterType(declaredTypeParameters[i]);
-        }
-        overriddenType = substituteTypeParams(
-            overriddenType, substitutionMap, declaredTypeParameters);
-      }
-      overriddenTypes.add(overriddenType);
-    }
-    return overriddenTypes;
-  }
-
-  void inferMethodType(LibraryBuilder library, Class class_, Procedure method,
-      List<Member> candidates, int start, int end) {
-    var overriddenTypes =
-        _computeMethodOverriddenTypes(class_, method, candidates, start, end);
-    if (ShadowProcedure.hasImplicitReturnType(method) &&
-        method.name != indexSetName) {
-      method.function.returnType = matchTypes(
-          overriddenTypes.map((type) => type.returnType),
-          library,
-          method.name.name,
-          class_.fileUri,
-          method.fileOffset);
-    }
-    var positionalParameters = method.function.positionalParameters;
-    for (int i = 0; i < positionalParameters.length; ++i) {
-      if (VariableDeclarationJudgment.isImplicitlyTyped(
-          positionalParameters[i])) {
-        // Note that if the parameter is not present in the overridden method,
-        // getPositionalParameterType treats it as dynamic.  This is consistent
-        // with the behavior called for in the informal top level type inference
-        // spec, which says:
-        //
-        //     If there is no corresponding parameter position in the overridden
-        //     method to infer from and the signatures are compatible, it is
-        //     treated as dynamic (e.g. overriding a one parameter method with a
-        //     method that takes a second optional parameter).  Note: if there
-        //     is no corresponding parameter position in the overridden method to
-        //     infer from and the signatures are incompatible (e.g. overriding a
-        //     one parameter method with a method that takes a second
-        //     non-optional parameter), the inference result is not defined and
-        //     tools are free to either emit an error, or to defer the error to
-        //     override checking.
-        positionalParameters[i].type = matchTypes(
-            overriddenTypes.map((type) => getPositionalParameterType(type, i)),
-            library,
-            positionalParameters[i].name,
-            class_.fileUri,
-            positionalParameters[i].fileOffset);
-      }
-    }
-    var namedParameters = method.function.namedParameters;
-    for (int i = 0; i < namedParameters.length; i++) {
-      if (VariableDeclarationJudgment.isImplicitlyTyped(namedParameters[i])) {
-        var name = namedParameters[i].name;
-        namedParameters[i].type = matchTypes(
-            overriddenTypes.map((type) => getNamedParameterType(type, name)),
-            library,
-            namedParameters[i].name,
-            class_.fileUri,
-            namedParameters[i].fileOffset);
-      }
-    }
-  }
-
-  /// Populates [getters] and [setters] with the members of the given [class_]'s
-  /// interface.
-  ///
-  /// [getters] will contain methods and getters, [setters] will contain
-  /// setters.  Some members cannot be resolved immediately.  For instance,
-  /// top-level type inference has not yet inferred field types based on
-  /// initializers and so we cannot yet do override based resolution of getters
-  /// and setters.  Members of the class's interface that need to be resolved
-  /// later are represented by a [ForwardingNode] object.
-  void createApiMembers(Class class_, List<Member> getters,
-      List<Member> setters, LibraryBuilder library) {
-    var candidates = ClassHierarchy.mergeSortedLists(
-        getCandidates(class_, false), getCandidates(class_, true));
-    // Now create getter and perhaps setter forwarding nodes for each unique
-    // name.
-    getters.length = candidates.length;
-    setters.length = candidates.length;
-    int getterIndex = 0;
-    int setterIndex = 0;
-    // To detect conflicts between instance members (possibly inherited ones)
-    // and static members, use a map from names to lists of members.  There can
-    // be more than one static member with a given name, e.g., if there is a
-    // getter and a setter.  We will report both conflicts.
-    forEachApiMember(candidates, (int start, int end, Name name) {
-      Procedure member = candidates[start];
-      ProcedureKind kind = _kindOf(member);
-      if (kind != ProcedureKind.Getter && kind != ProcedureKind.Setter) {
-        for (int i = start + 1; i < end; ++i) {
-          if (_kindOf(candidates[i]) != kind) return;
-        }
-        if (member.enclosingClass == class_ && _requiresTypeInference(member)) {
-          inferMethodType(library, class_, member, candidates, start + 1, end);
-        }
-        var forwardingNode = new ForwardingNode(
-            this, null, class_, name, kind, candidates, start, end);
-        getters[getterIndex++] = forwardingNode.finalize();
-        if (library is KernelLibraryBuilder &&
-            forwardingNode.finalize() != forwardingNode.resolve()) {
-          library.forwardersOrigins.add(forwardingNode.finalize());
-          library.forwardersOrigins.add(forwardingNode.resolve());
-        }
-        return;
-      }
-
-      Procedure declaredGetter;
-      int inheritedGetterStart = start;
-      int getterEnd = start;
-      if (kind == ProcedureKind.Getter) {
-        if (member.enclosingClass == class_) {
-          declaredGetter = member;
-          ++inheritedGetterStart;
-        }
-        while (++getterEnd < end) {
-          ProcedureKind currentKind = _kindOf(candidates[getterEnd]);
-          if (currentKind == ProcedureKind.Setter) break;
-          if (currentKind != ProcedureKind.Getter) return;
-        }
-      }
-
-      Procedure declaredSetter;
-      int inheritedSetterStart = getterEnd;
-      if (getterEnd < end) {
-        member = candidates[getterEnd];
-        if (member.enclosingClass == class_) {
-          declaredSetter = member;
-          ++inheritedSetterStart;
-        }
-      }
-
-      InferenceNode getterInferenceNode;
-      if (start < getterEnd) {
-        if (declaredGetter != null) {
-          getterInferenceNode = _createInferenceNode(
-              class_,
-              declaredGetter,
-              candidates,
-              inheritedGetterStart,
-              getterEnd,
-              inheritedSetterStart,
-              end,
-              library,
-              class_.fileUri);
-        }
-        // Getters need to be resolved later, as part of type inference, so just
-        // save the forwarding node for now.
-        //
-        // Choose a representative to use for error reporting, such as if a
-        // class inherits this getter and tries to declare a method with the
-        // same name.
-        Member representative = candidates[start];
-        getters[getterIndex++] = new ForwardingNode(this, getterInferenceNode,
-            class_, name, ProcedureKind.Getter, candidates, start, getterEnd)
-          ..fileUri = representative.fileUri
-          ..fileOffset = representative.fileOffset
-          ..fileEndOffset = representative.fileEndOffset;
-      }
-      if (getterEnd < end) {
-        InferenceNode setterInferenceNode;
-        if (declaredSetter != null) {
-          setterInferenceNode = declaredSetter is SyntheticAccessor
-              ? getterInferenceNode
-              : _createInferenceNode(
-                  class_,
-                  declaredSetter,
-                  candidates,
-                  inheritedSetterStart,
-                  end,
-                  inheritedGetterStart,
-                  getterEnd,
-                  library,
-                  class_.fileUri);
-        }
-        Member representative = candidates[getterEnd];
-        var forwardingNode = new ForwardingNode(this, setterInferenceNode,
-            class_, name, ProcedureKind.Setter, candidates, getterEnd, end)
-          ..fileUri = representative.fileUri
-          ..fileOffset = representative.fileOffset
-          ..fileEndOffset = representative.fileEndOffset;
-        // Setters need to be resolved later, as part of type inference, so just
-        // save the forwarding node for now.
-        setters[setterIndex++] = forwardingNode;
-      }
-    });
-    getters.length = getterIndex;
-    setters.length = setterIndex;
-  }
-
-  void finalizeCovariance(
-      Class class_, List<Member> apiMembers, LibraryBuilder library) {
-    for (int i = 0; i < apiMembers.length; i++) {
-      var member = apiMembers[i];
-      Member resolution;
-      if (member is ForwardingNode) {
-        apiMembers[i] = resolution = member.finalize();
-        if (library is KernelLibraryBuilder &&
-            member.finalize() != member.resolve()) {
-          library.forwardersOrigins.add(member.finalize());
-          library.forwardersOrigins.add(member.resolve());
-        }
-      } else {
-        resolution = member;
-      }
-      if (resolution is Procedure &&
-          resolution.isSyntheticForwarder &&
-          identical(resolution.enclosingClass, class_)) {
-        class_.addMember(resolution);
-      }
-    }
-  }
-
-  /// Gets a list of members implemented or potentially inherited by [class_],
-  /// sorted so that members with the same name are contiguous.
-  ///
-  /// If [setters] is `true`, setters are reported; otherwise getters, methods,
-  /// and operators are reported.
-  List<Procedure> getCandidates(Class class_, bool setters) {
-    // First create a list of candidates for inheritance based on the members
-    // declared directly in the class.
-    List<Procedure> candidates = _typeEnvironment.hierarchy
-        .getDeclaredMembers(class_, setters: setters)
-        .map((member) => makeCandidate(member, setters))
-        .toList();
-    // Merge in candidates from superclasses.
-    if (class_.superclass != null) {
-      candidates = _mergeCandidates(candidates, class_.superclass, setters);
-    }
-    for (var supertype in class_.implementedTypes) {
-      candidates = _mergeCandidates(candidates, supertype.classNode, setters);
-    }
-    return candidates;
-  }
-
-  /// Creates the appropriate [InferenceNode] for inferring [procedure] in the
-  /// context of [class_].
-  ///
-  /// [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.
-  ///
-  /// For getters and setters, [crossStart] and [crossEnd] are the start and end
-  /// indices of the corresponding overridden setters/getters, respectively.
-  InferenceNode _createInferenceNode(
-      Class class_,
-      Procedure procedure,
-      List<Member> candidates,
-      int start,
-      int end,
-      int crossStart,
-      int crossEnd,
-      LibraryBuilder library,
-      Uri fileUri) {
-    InferenceNode node;
-    if (procedure.isAccessor && _requiresTypeInference(procedure)) {
-      if (start < end) {
-        node = new AccessorInferenceNode(
-            this, procedure, candidates, start, end, library, fileUri);
-      } else if (crossStart < crossEnd) {
-        node = new AccessorInferenceNode(this, procedure, candidates,
-            crossStart, crossEnd, library, fileUri);
-      } else if (procedure is SyntheticAccessor &&
-          procedure._field.initializer != null) {
-        node = new FieldInitializerInferenceNode(
-            _typeInferenceEngine, procedure._field, library);
-      }
-
-      if (node != null && procedure is SyntheticAccessor) {
-        ShadowField.setInferenceNode(procedure._field, node);
-      }
-    }
-    return node;
-  }
-
-  /// Retrieves a list of the interface members of the given [class_].
-  ///
-  /// If [setters] is true, setters are retrieved; otherwise getters and methods
-  /// are retrieved.
-  List<Member> _getInterfaceMembers(Class class_, bool setters) {
-    // If class_ is being compiled from source, retrieve its forwarding nodes.
-    var inferenceInfo = ShadowClass.getClassInferenceInfo(class_);
-    if (inferenceInfo != null) {
-      return setters ? inferenceInfo.setters : inferenceInfo.gettersAndMethods;
-    } else {
-      return _typeEnvironment.hierarchy
-          .getInterfaceMembers(class_, setters: setters);
-    }
-  }
-
-  /// Merges together the list of interface inheritance candidates in
-  /// [candidates] with interface inheritance candidates from superclass
-  /// [class_].
-  ///
-  /// Any candidates from [class_] are converted into interface inheritance
-  /// candidates using [_makeCandidate].
-  List<Procedure> _mergeCandidates(
-      List<Procedure> candidates, Class class_, bool setters) {
-    List<Member> members = _getInterfaceMembers(class_, setters);
-    if (candidates.isEmpty) {
-      return members.map((member) => makeCandidate(member, setters)).toList();
-    }
-    if (members.isEmpty) return candidates;
-    List<Procedure> result = <Procedure>[]..length =
-        candidates.length + members.length;
-    int storeIndex = 0;
-    int i = 0, j = 0;
-    while (i < candidates.length && j < members.length) {
-      Procedure candidate = candidates[i];
-      Member member = members[j];
-      int compare = ClassHierarchy.compareMembers(candidate, member);
-      if (compare <= 0) {
-        result[storeIndex++] = candidate;
-        ++i;
-        // If the same member occurs in both lists, skip the duplicate.
-        if (identical(candidate, member)) ++j;
-      } else {
-        result[storeIndex++] = makeCandidate(member, setters);
-        ++j;
-      }
-    }
-    while (i < candidates.length) {
-      result[storeIndex++] = candidates[i++];
-    }
-    while (j < members.length) {
-      result[storeIndex++] = makeCandidate(members[j++], setters);
-    }
-    result.length = storeIndex;
-    return result;
-  }
-
-  /// Determines the appropriate substitution to translate type parameters
-  /// mentioned in the given [candidate] to type parameters on [class_].
-  Substitution _substitutionFor(Procedure candidate, Class class_) {
-    return Substitution.fromInterfaceType(_typeEnvironment.getTypeAsInstanceOf(
-        class_.thisType, candidate.enclosingClass));
-  }
-
-  /// Executes [callback] once for each uniquely named member of [candidates].
-  ///
-  /// The [start] and [end] values passed to [callback] are the start and
-  /// past-the-end indices into [candidates] of a group of members having the
-  /// same name.  The [name] value passed to [callback] is the common name.
-  static void forEachApiMember(
-      List<Member> candidates, void callback(int start, int end, Name name)) {
-    int i = 0;
-    while (i < candidates.length) {
-      var name = candidates[i].name;
-      int j = i + 1;
-      while (j < candidates.length && candidates[j].name == name) {
-        j++;
-      }
-      callback(i, j, name);
-      i = j;
-    }
-  }
-
-  /// Transforms [member] into a candidate for interface inheritance.
-  ///
-  /// Fields are transformed into getters and setters; methods are passed
-  /// through unchanged.
-  static Procedure makeCandidate(Member member, bool setter) {
-    if (member is Procedure) return member;
-    if (member is Field) {
-      // TODO(paulberry): don't set the type or covariance annotations here,
-      // since they might not have been inferred yet.  Instead, ensure that this
-      // information is propagated to the getter/setter during type inference.
-      var type = member.type;
-      var isGenericCovariantImpl = member.isGenericCovariantImpl;
-      var isCovariant = member.isCovariant;
-      if (setter) {
-        var valueParam = new VariableDeclaration('_', type: type)
-          ..isGenericCovariantImpl = isGenericCovariantImpl
-          ..isCovariant = isCovariant;
-        var function = new FunctionNode(null,
-            positionalParameters: [valueParam], returnType: const VoidType());
-        return new SyntheticAccessor(
-            member.name, ProcedureKind.Setter, function, member)
-          ..parent = member.enclosingClass;
-      } else {
-        var function = new FunctionNode(null, returnType: type);
-        return new SyntheticAccessor(
-            member.name, ProcedureKind.Getter, function, member)
-          ..parent = member.enclosingClass;
-      }
-    }
-    return unhandled('${member.runtimeType}', 'makeCandidate', -1, null);
-  }
-
-  static ProcedureKind _kindOf(Procedure procedure) => procedure.kind;
-
-  /// Determines whether the given [procedure] will require type inference.
-  static bool _requiresTypeInference(Procedure procedure) {
-    if (procedure is SyntheticAccessor) {
-      return ShadowField.isImplicitlyTyped(procedure._field);
-    }
-    if (procedure.kind != ProcedureKind.Setter &&
-        ShadowProcedure.hasImplicitReturnType(procedure)) {
-      // Inference of the return type of `[]=` is handled separately by
-      // KernelProcedureBuilder.build, since there are no dependencies.
-      if (procedure.kind != ProcedureKind.Operator ||
-          procedure.name.name != '[]=') {
-        return true;
-      }
-    }
-    var function = procedure.function;
-    for (var parameter in function.positionalParameters) {
-      if (VariableDeclarationJudgment.isImplicitlyTyped(parameter)) return true;
-    }
-    for (var parameter in function.namedParameters) {
-      if (VariableDeclarationJudgment.isImplicitlyTyped(parameter)) return true;
-    }
-    return false;
-  }
-}
-
-/// A [SyntheticAccessor] represents the getter or setter implied by a field.
-class SyntheticAccessor extends Procedure {
-  /// The field associated with the synthetic accessor.
-  final Field _field;
-
-  SyntheticAccessor(
-      Name name, ProcedureKind kind, FunctionNode function, this._field)
-      : super(
-            name,
-            kind,
-            kind == ProcedureKind.Setter
-                ? new SyntheticAccessorFunctionNode.setter(_field)
-                : new SyntheticAccessorFunctionNode.getter(_field),
-            fileUri: _field.fileUri) {
-    fileOffset = _field.fileOffset;
-  }
-
-  @override
-  DartType get getterType => _field.type;
-
-  static getField(SyntheticAccessor accessor) => accessor._field;
-}
-
-/// A [SyntheticAccessorFunctionNode] represents the [FunctionNode] part of the
-/// getter or setter implied by a field.
-///
-/// For getters, [returnType] maps to the underlying field's type, so that if
-/// type inference fills in the type of the field, the change will automatically
-/// be reflected in the synthetic getter.
-class SyntheticAccessorFunctionNode extends FunctionNode {
-  final Field _field;
-
-  SyntheticAccessorFunctionNode.getter(this._field)
-      : super(new ReturnStatement());
-
-  SyntheticAccessorFunctionNode.setter(this._field)
-      : super(new ReturnStatement(),
-            positionalParameters: [new SyntheticSetterParameter(_field)]);
-
-  @override
-  DartType get returnType =>
-      positionalParameters.isEmpty ? _field.type : const VoidType();
-}
-
-/// A [SyntheticSetterParameter] represents the "value" parameter of the setter
-/// implied by a field.
-///
-/// The getters [isCovariant], [isGenericCovariantImpl],
-/// [isGenericCovariantInterface], and [type] map to the underlying field's
-/// properties, so that if these properties are modified on the field, the
-/// change will automatically be reflected in the synthetic setter.  Similarly,
-/// the setters [isCovariant], [isGenericCovariantImpl], and
-/// [isGenericCovariantInterface] update the corresponding properties on the
-/// field, so that covariance propagation logic can act uniformly on [Procedure]
-/// objects without having to have special case handling for fields.
-class SyntheticSetterParameter extends VariableDeclaration {
-  final Field _field;
-
-  SyntheticSetterParameter(this._field)
-      : super('_', isCovariant: _field.isCovariant);
-
-  @override
-  bool get isCovariant => _field.isCovariant;
-
-  @override
-  void set isCovariant(bool value) {
-    _field.isCovariant = value;
-  }
-
-  @override
-  bool get isGenericCovariantImpl => _field.isGenericCovariantImpl;
-
-  @override
-  void set isGenericCovariantImpl(bool value) {
-    _field.isGenericCovariantImpl = value;
-  }
-
-  @override
-  DartType get type => _field.type;
-}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index bbf090a..b28fc43 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -11,7 +11,6 @@
         Field,
         FunctionType,
         InterfaceType,
-        InvalidType,
         Member,
         TypeParameter,
         TypeParameterType,
@@ -25,63 +24,16 @@
 import '../../base/instrumentation.dart' show Instrumentation;
 
 import '../kernel/kernel_builder.dart'
-    show LibraryBuilder, KernelLibraryBuilder;
+    show
+        ClassHierarchyBuilder,
+        ImplicitFieldType,
+        LibraryBuilder,
+        KernelLibraryBuilder;
 
-import '../kernel/kernel_shadow_ast.dart' show ShadowField, ShadowMember;
-
-import '../messages.dart' show noLength, templateCantInferTypeDueToCircularity;
-
-import 'type_inferrer.dart' show TypeInferrer, TypeInferrerImpl;
+import 'type_inferrer.dart' show TypeInferrer;
 
 import 'type_schema_environment.dart' show TypeSchemaEnvironment;
 
-/// Concrete class derived from [InferenceNode] to represent type inference of a
-/// field based on its initializer.
-class FieldInitializerInferenceNode extends InferenceNode {
-  final TypeInferenceEngine _typeInferenceEngine;
-
-  /// The field whose type should be inferred.
-  final ShadowField field;
-
-  final LibraryBuilder _library;
-
-  FieldInitializerInferenceNode(
-      this._typeInferenceEngine, this.field, this._library);
-
-  @override
-  void resolveInternal() {
-    var typeInferrer = _typeInferenceEngine.getFieldTypeInferrer(field);
-    // Note: in the event that there is erroneous code, it's possible for
-    // typeInferrer to be null.  If this happens, just skip type inference for
-    // this field.
-    if (typeInferrer != null) {
-      var inferredType = typeInferrer
-          .inferDeclarationType(typeInferrer.inferFieldTopLevel(field));
-      if (isCircular) {
-        // Report the appropriate error.
-        _library.addProblem(
-            templateCantInferTypeDueToCircularity
-                .withArguments(field.name.name),
-            field.fileOffset,
-            noLength,
-            field.fileUri);
-        inferredType = const InvalidType();
-      }
-      field.setInferredType(
-          _typeInferenceEngine, typeInferrer.uri, inferredType);
-      // TODO(paulberry): if type != null, then check that the type of the
-      // initializer is assignable to it.
-    }
-    // TODO(paulberry): the following is a hack so that outlines don't contain
-    // initializers.  But it means that we rebuild the initializers when doing
-    // a full compile.  There should be a better way.
-    field.initializer = null;
-  }
-
-  @override
-  String toString() => field.toString();
-}
-
 /// Visitor to check whether a given type mentions any of a class's type
 /// parameters in a covariant fashion.
 class IncludesTypeParametersCovariantly extends DartTypeVisitor<bool> {
@@ -131,67 +83,6 @@
   }
 }
 
-/// Base class for tracking dependencies during top level type inference.
-///
-/// Fields, accessors, and methods can have their types inferred in a variety of
-/// ways; there will a derived class for each kind of inference.
-abstract class InferenceNode {
-  /// The node currently being evaluated, or `null` if no node is being
-  /// evaluated.
-  static InferenceNode _currentNode;
-
-  /// Indicates whether the type inference corresponding to this node has been
-  /// completed.
-  bool _isResolved = false;
-
-  /// Indicates whether this node participates in a circularity.
-  bool _isCircular = false;
-
-  /// If this node is currently being evaluated, and its evaluation caused a
-  /// recursive call to another node's [resolve] method, a pointer to the latter
-  /// node; otherwise `null`.
-  InferenceNode _nextNode;
-
-  /// Indicates whether this node participates in a circularity.
-  ///
-  /// This may be called at the end of [resolveInternal] to check whether a
-  /// circularity was detected during evaluation.
-  bool get isCircular => _isCircular;
-
-  /// Evaluates this node, properly accounting for circularities.
-  void resolve() {
-    if (_isResolved) return;
-    if (_nextNode != null || identical(_currentNode, this)) {
-      // An accessor depends on itself (possibly by way of intermediate
-      // accessors).  Mark all accessors involved as circular.
-      var node = this;
-      do {
-        node._isCircular = true;
-        node._isResolved = true;
-        node = node._nextNode;
-      } while (node != null);
-    } else {
-      var previousNode = _currentNode;
-      assert(previousNode?._nextNode == null);
-      _currentNode = this;
-      previousNode?._nextNode = this;
-      resolveInternal();
-      assert(identical(_currentNode, this));
-      previousNode?._nextNode = null;
-      _currentNode = previousNode;
-      _isResolved = true;
-    }
-  }
-
-  /// Evaluates this node, possibly by making recursive calls to the [resolve]
-  /// method of this node or other nodes.
-  ///
-  /// Circularity detection is handled by [resolve], which calls this method.
-  /// Once this method has made all recursive calls to [resolve], it may use
-  /// [isCircular] to detect whether a circularity has occurred.
-  void resolveInternal();
-}
-
 /// Keeps track of the global state for the type inference that occurs outside
 /// of method bodies and initializers.
 ///
@@ -201,6 +92,8 @@
 abstract class TypeInferenceEngine {
   ClassHierarchy classHierarchy;
 
+  ClassHierarchyBuilder hierarchyBuilder;
+
   CoreTypes coreTypes;
 
   /// Indicates whether the "prepare" phase of type inference is complete.
@@ -208,8 +101,6 @@
 
   TypeSchemaEnvironment typeSchemaEnvironment;
 
-  final staticInferenceNodes = <FieldInitializerInferenceNode>[];
-
   /// A map containing constructors with initializing formals whose types
   /// need to be inferred.
   ///
@@ -237,21 +128,7 @@
   /// Creates a [TypeInferrer] object which is ready to perform type inference
   /// on the given [field].
   TypeInferrer createTopLevelTypeInferrer(
-      InterfaceType thisType, ShadowField field, KernelLibraryBuilder library);
-
-  /// Retrieve the [TypeInferrer] for the given [field], which was created by
-  /// a previous call to [createTopLevelTypeInferrer].
-  TypeInferrerImpl getFieldTypeInferrer(ShadowField field);
-
-  /// Performs the second phase of top level initializer inference, which is to
-  /// visit all accessors and top level variables that were passed to
-  /// [recordAccessor] in topologically-sorted order and assign their types.
-  void finishTopLevelFields() {
-    for (var node in staticInferenceNodes) {
-      node.resolve();
-    }
-    staticInferenceNodes.clear();
-  }
+      Uri uri, InterfaceType thisType, KernelLibraryBuilder library);
 
   /// Performs the third phase of top level inference, which is to visit all
   /// constructors still needing inference and infer the types of their
@@ -295,20 +172,17 @@
         new TypeSchemaEnvironment(coreTypes, hierarchy);
   }
 
-  /// Records that the given static [field] will need top level type inference.
-  void recordStaticFieldInferenceCandidate(
-      ShadowField field, LibraryBuilder library) {
-    var node = new FieldInitializerInferenceNode(this, field, library);
-    ShadowField.setInferenceNode(field, node);
-    staticInferenceNodes.add(node);
-  }
-
-  static void resolveInferenceNode(Member member) {
-    if (member is ShadowMember) {
-      if (member.inferenceNode != null) {
-        member.inferenceNode.resolve();
-        member.inferenceNode = null;
+  static Member resolveInferenceNode(Member member) {
+    if (member is Field) {
+      DartType type = member.type;
+      if (type is ImplicitFieldType) {
+        if (type.member.target != member) {
+          type.member.inferCopiedType(member);
+        } else {
+          type.member.inferType();
+        }
       }
     }
+    return member;
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index bbe6899..5c01672 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -103,8 +103,6 @@
 import '../kernel/kernel_shadow_ast.dart'
     show
         ExpressionJudgment,
-        ShadowClass,
-        ShadowField,
         ShadowTypeInferenceEngine,
         ShadowTypeInferrer,
         VariableDeclarationJudgment,
@@ -119,8 +117,6 @@
 
 import 'inference_helper.dart' show InferenceHelper;
 
-import 'interface_resolver.dart' show ForwardingNode, SyntheticAccessor;
-
 import 'type_constraint_gatherer.dart' show TypeConstraintGatherer;
 
 import 'type_inference_engine.dart'
@@ -750,7 +746,8 @@
     Class classNode = receiverType is InterfaceType
         ? receiverType.classNode
         : coreTypes.objectClass;
-    Member interfaceMember = _getInterfaceMember(classNode, name, setter);
+    Member interfaceMember =
+        _getInterfaceMember(classNode, name, setter, fileOffset);
     if (instrumented &&
         receiverType != const DynamicType() &&
         interfaceMember != null) {
@@ -911,7 +908,8 @@
     if (calleeType is FunctionType) {
       return calleeType;
     } else if (followCall && calleeType is InterfaceType) {
-      var member = _getInterfaceMember(calleeType.classNode, callName, false);
+      var member =
+          _getInterfaceMember(calleeType.classNode, callName, false, -1);
       var callType = getCalleeType(member, calleeType);
       if (callType is FunctionType) {
         return callType;
@@ -969,7 +967,7 @@
 
   /// Gets the initializer for the given [field], or `null` if there is no
   /// initializer.
-  Expression getFieldInitializer(ShadowField field);
+  Expression getFieldInitializer(Field field);
 
   /// If the [member] is a forwarding stub, return the target it forwards to.
   /// Otherwise return the given [member].
@@ -1160,12 +1158,6 @@
     this.helper = null;
   }
 
-  /// Performs type inference on the given [field]'s initializer expression.
-  ///
-  /// Derived classes should provide an implementation that calls
-  /// [inferExpression] for the given [field]'s initializer expression.
-  DartType inferFieldTopLevel(ShadowField field);
-
   @override
   void inferFunctionBody(InferenceHelper helper, DartType returnType,
       AsyncMarker asyncMarker, Statement body) {
@@ -1830,25 +1822,16 @@
     }
   }
 
-  Member _getInterfaceMember(Class class_, Name name, bool setter) {
-    if (class_ is ShadowClass) {
-      var classInferenceInfo = ShadowClass.getClassInferenceInfo(class_);
-      if (classInferenceInfo != null) {
-        var member = ClassHierarchy.findMemberByName(
-            setter
-                ? classInferenceInfo.setters
-                : classInferenceInfo.gettersAndMethods,
-            name);
-        if (member == null) return null;
-        member = member is ForwardingNode ? member.resolve() : member;
-        member = member is SyntheticAccessor
-            ? SyntheticAccessor.getField(member)
-            : member;
-        TypeInferenceEngine.resolveInferenceNode(member);
-        return member;
-      }
+  Member _getInterfaceMember(
+      Class class_, Name name, bool setter, int charOffset) {
+    Member member = engine.hierarchyBuilder.getCombinedMemberSignatureKernel(
+        class_, name, setter, charOffset, library);
+    if (member == null && (library?.isPatch ?? false)) {
+      // TODO(dmitryas): Hack for parts.
+      member ??=
+          classHierarchy.getInterfaceMember(class_, name, setter: setter);
     }
-    return classHierarchy.getInterfaceMember(class_, name, setter: setter);
+    return TypeInferenceEngine.resolveInferenceNode(member);
   }
 
   /// Determines if the given [expression]'s type is precisely known at compile
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 0ea1a63..9446be4 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -44,7 +44,6 @@
 CantInferPackagesFromPackageUri/analyzerCode: Fail
 CantInferPackagesFromPackageUri/example: Fail
 CantInferTypeDueToCircularity/example: Fail
-CantInferTypeDueToInconsistentOverrides/example: Fail
 CantReadFile/part_wrapped_script: Fail # Importing file in the (now) part.
 CantUseControlFlowOrSpreadAsConstant/example: Fail
 CantUseDeferredPrefixAsConstant/part_wrapped_script: Fail # Importing file in the (now) part.
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index d94388d..b0ff217 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -2926,6 +2926,13 @@
   template: "Can't infer a type for '#name' as some of the inherited members have different types."
   tip: "Try adding an explicit type."
   analyzerCode: INVALID_METHOD_OVERRIDE
+  external: testcases/inference/inconsistent_overrides.dart
+
+CantInferReturnTypeDueToInconsistentOverrides:
+  template: "Can't infer a return type for '#name' as some of the inherited members have different types."
+  tip: "Try adding an explicit type."
+  analyzerCode: INVALID_METHOD_OVERRIDE
+  external: testcases/inference/inconsistent_overrides.dart
 
 CantInferTypeDueToCircularity:
   template: "Can't infer the type of '#string': circularity found during type inference."
@@ -3569,3 +3576,19 @@
 
 BytecodeLimitExceededTooManyArguments:
   template: "Dart bytecode limit exceeded: too many arguments."
+
+CombinedMemberSignatureFailed:
+  template: "Class '#name' inherits multiple members named '#name2' with incompatible signatures."
+  tip: "Try adding a declaration of '#name2' to '#name'."
+  analyzerCode: INCONSISTENT_INHERITANCE
+  script:
+    - |
+      abstract class I1 {
+        foo(x);
+      }
+
+      abstract class I2 {
+        foo();
+      }
+
+      abstract class C implements I2, I1 {}
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index c183abd..87a52d9 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -368,7 +368,7 @@
       UriTranslator uriTranslator = new UriTranslator(
           const TargetLibrariesSpecification('vm'),
           context.uriTranslator.packages);
-      KernelTarget sourceTarget = new KernelTestingTarget(
+      KernelTarget sourceTarget = new KernelTarget(
           StandardFileSystem.instance, false, dillTarget, uriTranslator);
 
       sourceTarget.setEntryPoints(<Uri>[description.uri]);
@@ -463,15 +463,6 @@
   }
 }
 
-class KernelTestingTarget extends KernelTarget {
-  @override
-  ClassHierarchyBuilder builderHierarchy;
-
-  KernelTestingTarget(StandardFileSystem fileSystem, bool includeComments,
-      DillTarget dillTarget, UriTranslator uriTranslator)
-      : super(fileSystem, includeComments, dillTarget, uriTranslator);
-}
-
 class MatchHierarchy extends Step<Component, Component, FastaContext> {
   const MatchHierarchy();
 
@@ -481,8 +472,8 @@
       Component component, FastaContext context) async {
     Uri uri =
         component.uriToSource.keys.firstWhere((uri) => uri?.scheme == "file");
-    KernelTestingTarget target = context.componentToTarget[component];
-    ClassHierarchyBuilder hierarchy = target.builderHierarchy;
+    KernelTarget target = context.componentToTarget[component];
+    ClassHierarchyBuilder hierarchy = target.loader.builderHierarchy;
     StringBuffer sb = new StringBuffer();
     for (ClassHierarchyNode node in hierarchy.nodes.values) {
       node.toString(sb);
diff --git a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart b/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
deleted file mode 100644
index b19a80f..0000000
--- a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
+++ /dev/null
@@ -1,1049 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart';
-import 'package:front_end/src/fasta/type_inference/interface_resolver.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
-import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/core_types.dart';
-import 'package:kernel/testing/mock_sdk_component.dart';
-import 'package:kernel/type_algebra.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(InterfaceResolverTest);
-  });
-}
-
-@reflectiveTest
-class InterfaceResolverTest {
-  final Library testLib;
-
-  final Component component;
-
-  final CoreTypes coreTypes;
-
-  ClassHierarchy cachedClassHierarchy;
-
-  TypeSchemaEnvironment cachedTypeEnvironment;
-
-  InterfaceResolver cachedInterfaceResolver;
-
-  InterfaceResolverTest()
-      : this._(new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib'),
-            createMockSdkComponent());
-
-  InterfaceResolverTest._(this.testLib, Component component)
-      : component = component..libraries.add(testLib..parent = component),
-        coreTypes = new CoreTypes(component);
-
-  ClassHierarchy get classHierarchy {
-    return cachedClassHierarchy ??= new ClassHierarchy(component);
-  }
-
-  TypeSchemaEnvironment get typeEnvironment {
-    return cachedTypeEnvironment ??=
-        new TypeSchemaEnvironment(coreTypes, classHierarchy);
-  }
-
-  InterfaceResolver get interfaceResolver {
-    return cachedInterfaceResolver ??=
-        new InterfaceResolver(null, typeEnvironment, null);
-  }
-
-  InterfaceType get intType => coreTypes.intClass.rawType;
-
-  Class get listClass => coreTypes.listClass;
-
-  InterfaceType get numType => coreTypes.numClass.rawType;
-
-  Class get objectClass => coreTypes.objectClass;
-
-  InterfaceType get objectType => objectClass.rawType;
-
-  void checkCandidate(Procedure procedure, bool setter) {
-    var class_ = makeClass(procedures: [procedure]);
-    var candidate = getCandidate(class_, setter);
-    expect(candidate, same(procedure));
-  }
-
-  void checkCandidateOrder(Class class_, Member member) {
-    // Check that InterfaceResolver prioritizes [member]
-    var candidates = getCandidates(class_, false);
-    expect(candidates[0], same(member));
-
-    // Check that both implementations of [ClassHierarchy] prioritize [member]
-    // ahead of [other]
-    void check(ClassHierarchy classHierarchy) {
-      var interfaceMember =
-          classHierarchy.getInterfaceMember(class_, member.name);
-      expect(interfaceMember, same(member));
-    }
-
-    check(new ClassHierarchy(component));
-  }
-
-  Procedure getCandidate(Class class_, bool setter) {
-    var candidates = getCandidates(class_, setter);
-    expect(candidates, hasLength(1));
-    return candidates[0];
-  }
-
-  List<Procedure> getCandidates(Class class_, bool setters) =>
-      interfaceResolver.getCandidates(class_, setters);
-
-  ForwardingNode getForwardingNode(Class class_, bool setter) {
-    var forwardingNodes = getForwardingNodes(class_, setter);
-    expect(forwardingNodes, hasLength(1));
-    return forwardingNodes[0];
-  }
-
-  List<ForwardingNode> getForwardingNodes(Class class_, bool setters) {
-    var forwardingNodes = <ForwardingNode>[];
-    var candidates = getCandidates(class_, setters);
-    InterfaceResolver.forEachApiMember(candidates,
-        (int start, int end, Name name) {
-      forwardingNodes.add(new ForwardingNode(interfaceResolver, null, class_,
-          name, candidates[start].kind, candidates, start, end));
-    });
-    return forwardingNodes;
-  }
-
-  Member getStubTarget(Procedure stub) {
-    var body = stub.function.body;
-    if (body == null) return null;
-    if (body is ReturnStatement) {
-      var expression = body.expression;
-      if (expression is SuperMethodInvocation) {
-        return expression.interfaceTarget;
-      } else if (expression is SuperPropertySet) {
-        return expression.interfaceTarget;
-      } else {
-        fail('Unexpected expression type: ${expression.runtimeType}');
-      }
-    } else {
-      fail('Unexpected body type: ${body.runtimeType}');
-    }
-  }
-
-  Class makeClass(
-      {String name,
-      Supertype supertype,
-      Supertype mixedInType,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes,
-      List<Procedure> procedures,
-      List<Field> fields}) {
-    resetInterfaceResolver();
-    var class_ = new ShadowClass(
-        name: name ?? 'C',
-        supertype: supertype ?? objectClass.asThisSupertype,
-        mixedInType: mixedInType,
-        typeParameters: typeParameters,
-        implementedTypes: implementedTypes,
-        procedures: procedures,
-        fields: fields);
-    testLib.addClass(class_);
-    return class_;
-  }
-
-  Procedure makeEmptyMethod(
-      {ProcedureKind kind: ProcedureKind.Method,
-      String name: 'foo',
-      List<TypeParameter> typeParameters,
-      List<VariableDeclaration> positionalParameters,
-      List<VariableDeclaration> namedParameters,
-      int requiredParameterCount,
-      DartType returnType: const VoidType(),
-      bool isAbstract: false}) {
-    var body = isAbstract ? null : new ReturnStatement(new NullLiteral());
-    var function = new FunctionNode(body,
-        typeParameters: typeParameters,
-        positionalParameters: positionalParameters,
-        namedParameters: namedParameters,
-        requiredParameterCount: requiredParameterCount,
-        returnType: returnType);
-    return new ShadowProcedure(new Name(name), kind, function, false,
-        isAbstract: isAbstract);
-  }
-
-  Field makeField(
-      {String name: 'foo',
-      DartType type: const DynamicType(),
-      bool isFinal: false}) {
-    return new Field(new Name(name), type: type, isFinal: isFinal);
-  }
-
-  Procedure makeForwardingStub(Procedure method, bool setter,
-      {Substitution substitution}) {
-    var a = makeClass(name: 'A', procedures: [method]);
-    var b = makeClass(name: 'B', supertype: a.asThisSupertype);
-    var node = getForwardingNode(b, setter);
-    var stub = ForwardingNode.createForwardingStubForTesting(
-        node, substitution ?? Substitution.empty, method);
-    ForwardingNode.createForwardingImplIfNeededForTesting(node, stub.function);
-    return stub;
-  }
-
-  Procedure makeGetter(
-      {String name: 'foo', DartType getterType: const DynamicType()}) {
-    var body = new ReturnStatement(new NullLiteral());
-    var function = new FunctionNode(body, returnType: getterType);
-    return new ShadowProcedure(
-        new Name(name), ProcedureKind.Getter, function, false);
-  }
-
-  Procedure makeSetter(
-      {String name: 'foo',
-      DartType setterType: const DynamicType(),
-      bool isCovariant: false}) {
-    var parameter = new VariableDeclarationJudgment('value', 0,
-        type: setterType, isCovariant: isCovariant);
-    var body = new Block([]);
-    var function = new FunctionNode(body,
-        positionalParameters: [parameter], returnType: const VoidType());
-    return new ShadowProcedure(
-        new Name(name), ProcedureKind.Setter, function, false);
-  }
-
-  void resetInterfaceResolver() {
-    cachedClassHierarchy = null;
-    cachedTypeEnvironment = null;
-    cachedInterfaceResolver = null;
-  }
-
-  void test_candidate_for_field_getter() {
-    var field = makeField();
-    var class_ = makeClass(fields: [field]);
-    var candidate = getCandidate(class_, false);
-    expect(candidate, const TypeMatcher<SyntheticAccessor>());
-    expect(candidate.parent, same(class_));
-    expect(candidate.name, field.name);
-    expect(candidate.kind, ProcedureKind.Getter);
-    expect(candidate.function.positionalParameters, isEmpty);
-    expect(candidate.function.namedParameters, isEmpty);
-    expect(candidate.function.typeParameters, isEmpty);
-  }
-
-  void test_candidate_for_field_setter() {
-    var field = makeField();
-    var class_ = makeClass(fields: [field]);
-    var candidate = getCandidate(class_, true);
-    expect(candidate, const TypeMatcher<SyntheticAccessor>());
-    expect(candidate.parent, same(class_));
-    expect(candidate.name, field.name);
-    expect(candidate.kind, ProcedureKind.Setter);
-    expect(candidate.function.positionalParameters, hasLength(1));
-    expect(candidate.function.positionalParameters[0].name, '_');
-    expect(candidate.function.namedParameters, isEmpty);
-    expect(candidate.function.typeParameters, isEmpty);
-    expect(candidate.function.returnType, const VoidType());
-  }
-
-  void test_candidate_for_getter() {
-    var function = new FunctionNode(null);
-    var getter = new ShadowProcedure(
-        new Name('foo'), ProcedureKind.Getter, function, false);
-    checkCandidate(getter, false);
-  }
-
-  void test_candidate_for_method() {
-    checkCandidate(makeEmptyMethod(), false);
-  }
-
-  void test_candidate_for_setter() {
-    var parameter = new VariableDeclarationJudgment('value', 0);
-    var function = new FunctionNode(null,
-        positionalParameters: [parameter], returnType: const VoidType());
-    var setter = new ShadowProcedure(
-        new Name('foo'), ProcedureKind.Setter, function, false);
-    checkCandidate(setter, true);
-  }
-
-  void test_candidate_from_interface() {
-    var method = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [method]);
-    var b = makeClass(name: 'B', implementedTypes: [a.asThisSupertype]);
-    var candidate = getCandidate(b, false);
-    expect(candidate, same(method));
-  }
-
-  void test_candidate_from_mixin() {
-    var method = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [method]);
-    var b = makeClass(name: 'B', mixedInType: a.asThisSupertype);
-    var candidate = getCandidate(b, false);
-    expect(candidate, same(method));
-  }
-
-  void test_candidate_from_superclass() {
-    var method = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [method]);
-    var b = makeClass(name: 'B', supertype: a.asThisSupertype);
-    var candidate = getCandidate(b, false);
-    expect(candidate, same(method));
-  }
-
-  void test_candidate_order_interfaces() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
-    checkCandidateOrder(c, methodA);
-  }
-
-  void test_candidate_order_mixin_before_superclass() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C',
-        supertype: a.asThisSupertype,
-        mixedInType: b.asThisSupertype);
-    checkCandidateOrder(c, methodB);
-  }
-
-  void test_candidate_order_superclass_before_interface() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C',
-        supertype: a.asThisSupertype,
-        implementedTypes: [b.asThisSupertype]);
-    checkCandidateOrder(c, methodA);
-  }
-
-  void test_createForwardingStub_abstract() {
-    var method = makeEmptyMethod(isAbstract: true);
-    var stub = makeForwardingStub(method, false);
-    expect(stub.isAbstract, isTrue);
-    expect(stub.function.body, isNull);
-  }
-
-  void test_createForwardingStub_getter() {
-    var getter = makeGetter(getterType: numType);
-    var stub = makeForwardingStub(getter, false);
-    expect(stub.name, getter.name);
-    expect(stub.kind, ProcedureKind.Getter);
-    expect(stub.function.positionalParameters, isEmpty);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 0);
-    expect(stub.function.returnType, numType);
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperPropertyGet;
-    expect(expression.name, getter.name);
-    expect(expression.interfaceTarget, same(getter));
-  }
-
-  void test_createForwardingStub_getter_for_field() {
-    var field = makeField(type: numType);
-    var stub = makeForwardingStub(
-        InterfaceResolver.makeCandidate(field, false), false);
-    expect(stub.name, field.name);
-    expect(stub.kind, ProcedureKind.Getter);
-    expect(stub.function.positionalParameters, isEmpty);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 0);
-    expect(stub.function.returnType, numType);
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperPropertyGet;
-    expect(expression.name, field.name);
-    expect(expression.interfaceTarget, same(field));
-  }
-
-  void test_createForwardingStub_operator() {
-    var operator = makeEmptyMethod(
-        kind: ProcedureKind.Operator,
-        name: '[]=',
-        positionalParameters: [
-          new VariableDeclarationJudgment('index', 0, type: intType),
-          new VariableDeclarationJudgment('value', 0, type: numType)
-        ]);
-    var stub = makeForwardingStub(operator, false);
-    expect(stub.name, operator.name);
-    expect(stub.kind, ProcedureKind.Operator);
-    expect(stub.function.positionalParameters, hasLength(2));
-    expect(stub.function.positionalParameters[0].name,
-        operator.function.positionalParameters[0].name);
-    expect(stub.function.positionalParameters[0].type, intType);
-    expect(stub.function.positionalParameters[1].name,
-        operator.function.positionalParameters[1].name);
-    expect(stub.function.positionalParameters[1].type, numType);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 2);
-    expect(stub.function.returnType, const VoidType());
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperMethodInvocation;
-    expect(expression.name, operator.name);
-    expect(expression.interfaceTarget, same(operator));
-    var arguments = expression.arguments;
-    expect(arguments.positional, hasLength(2));
-    expect((arguments.positional[0] as VariableGet).variable,
-        same(stub.function.positionalParameters[0]));
-    expect((arguments.positional[1] as VariableGet).variable,
-        same(stub.function.positionalParameters[1]));
-  }
-
-  void test_createForwardingStub_optionalNamedParameter() {
-    var parameter = new VariableDeclarationJudgment('x', 0, type: intType);
-    var method = makeEmptyMethod(namedParameters: [parameter]);
-    var stub = makeForwardingStub(method, false);
-    expect(stub.function.namedParameters, hasLength(1));
-    expect(stub.function.namedParameters[0].name, 'x');
-    expect(stub.function.namedParameters[0].type, intType);
-    expect(stub.function.requiredParameterCount, 0);
-    var arguments = ((stub.function.body as ReturnStatement).expression
-            as SuperMethodInvocation)
-        .arguments;
-    expect(arguments.named, hasLength(1));
-    expect(arguments.named[0].name, 'x');
-    expect((arguments.named[0].value as VariableGet).variable,
-        same(stub.function.namedParameters[0]));
-  }
-
-  void test_createForwardingStub_optionalPositionalParameter() {
-    var parameter = new VariableDeclarationJudgment('x', 0, type: intType);
-    var method = makeEmptyMethod(
-        positionalParameters: [parameter], requiredParameterCount: 0);
-    var stub = makeForwardingStub(method, false);
-    expect(stub.function.positionalParameters, hasLength(1));
-    expect(stub.function.positionalParameters[0].name, 'x');
-    expect(stub.function.positionalParameters[0].type, intType);
-    expect(stub.function.requiredParameterCount, 0);
-    var arguments = ((stub.function.body as ReturnStatement).expression
-            as SuperMethodInvocation)
-        .arguments;
-    expect(arguments.positional, hasLength(1));
-    expect((arguments.positional[0] as VariableGet).variable,
-        same(stub.function.positionalParameters[0]));
-  }
-
-  void test_createForwardingStub_requiredParameter() {
-    var parameter = new VariableDeclarationJudgment('x', 0, type: intType);
-    var method = makeEmptyMethod(positionalParameters: [parameter]);
-    var stub = makeForwardingStub(method, false);
-    expect(stub.function.positionalParameters, hasLength(1));
-    expect(stub.function.positionalParameters[0].name, 'x');
-    expect(stub.function.positionalParameters[0].type, intType);
-    expect(stub.function.requiredParameterCount, 1);
-    var arguments = ((stub.function.body as ReturnStatement).expression
-            as SuperMethodInvocation)
-        .arguments;
-    expect(arguments.positional, hasLength(1));
-    expect((arguments.positional[0] as VariableGet).variable,
-        same(stub.function.positionalParameters[0]));
-  }
-
-  void test_createForwardingStub_setter() {
-    var setter = makeSetter(setterType: numType);
-    var stub = makeForwardingStub(setter, true);
-    expect(stub.name, setter.name);
-    expect(stub.kind, ProcedureKind.Setter);
-    expect(stub.function.positionalParameters, hasLength(1));
-    expect(stub.function.positionalParameters[0].name,
-        setter.function.positionalParameters[0].name);
-    expect(stub.function.positionalParameters[0].type, numType);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 1);
-    expect(stub.function.returnType, const VoidType());
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperPropertySet;
-    expect(expression.name, setter.name);
-    expect(expression.interfaceTarget, same(setter));
-    expect((expression.value as VariableGet).variable,
-        same(stub.function.positionalParameters[0]));
-  }
-
-  void test_createForwardingStub_setter_for_field() {
-    var field = makeField(type: numType);
-    var stub =
-        makeForwardingStub(InterfaceResolver.makeCandidate(field, true), true);
-    expect(stub.name, field.name);
-    expect(stub.kind, ProcedureKind.Setter);
-    expect(stub.function.positionalParameters, hasLength(1));
-    expect(stub.function.positionalParameters[0].name, '_');
-    expect(stub.function.positionalParameters[0].type, numType);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 1);
-    expect(stub.function.returnType, const VoidType());
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperPropertySet;
-    expect(expression.name, field.name);
-    expect(expression.interfaceTarget, same(field));
-    expect((expression.value as VariableGet).variable,
-        same(stub.function.positionalParameters[0]));
-  }
-
-  void test_createForwardingStub_simple() {
-    var method = makeEmptyMethod();
-    var stub = makeForwardingStub(method, false);
-    expect(stub.name, method.name);
-    expect(stub.kind, ProcedureKind.Method);
-    expect(stub.isAbstract, isFalse);
-    expect(stub.function.positionalParameters, isEmpty);
-    expect(stub.function.namedParameters, isEmpty);
-    expect(stub.function.typeParameters, isEmpty);
-    expect(stub.function.requiredParameterCount, 0);
-    expect(stub.function.returnType, const VoidType());
-    var body = stub.function.body as ReturnStatement;
-    var expression = body.expression as SuperMethodInvocation;
-    expect(expression.name, method.name);
-    expect(expression.interfaceTarget, same(method));
-    expect(expression.arguments.positional, isEmpty);
-    expect(expression.arguments.named, isEmpty);
-    expect(expression.arguments.types, isEmpty);
-  }
-
-  void test_createForwardingStub_substitute() {
-    // class C<T> { T foo(T x, {T y}); }
-    var T = new TypeParameter('T', objectType);
-    var x =
-        new VariableDeclarationJudgment('x', 0, type: new TypeParameterType(T));
-    var y =
-        new VariableDeclarationJudgment('y', 0, type: new TypeParameterType(T));
-    var method = makeEmptyMethod(
-        positionalParameters: [x],
-        namedParameters: [y],
-        returnType: new TypeParameterType(T));
-    var substitution = Substitution.fromPairs([T], [intType]);
-    var stub = makeForwardingStub(method, false, substitution: substitution);
-    expect(stub.function.positionalParameters[0].type, intType);
-    expect(stub.function.namedParameters[0].type, intType);
-    expect(stub.function.returnType, intType);
-  }
-
-  void test_createForwardingStub_typeParameter() {
-    var typeParameter = new TypeParameter('T', numType);
-    var method = makeEmptyMethod(typeParameters: [typeParameter]);
-    var stub = makeForwardingStub(method, false);
-    expect(stub.function.typeParameters, hasLength(1));
-    expect(stub.function.typeParameters[0].name, 'T');
-    expect(stub.function.typeParameters[0].bound, numType);
-    var arguments = ((stub.function.body as ReturnStatement).expression
-            as SuperMethodInvocation)
-        .arguments;
-    expect(arguments.types, hasLength(1));
-    var typeArgument = arguments.types[0] as TypeParameterType;
-    expect(typeArgument.parameter, same(stub.function.typeParameters[0]));
-    expect(typeArgument.promotedBound, isNull);
-  }
-
-  void test_createForwardingStub_typeParameter_and_substitution() {
-    // class C<T> { void foo<U>(T x, U y); }
-    var T = new TypeParameter('T', objectType);
-    var U = new TypeParameter('U', objectType);
-    var x =
-        new VariableDeclarationJudgment('x', 0, type: new TypeParameterType(T));
-    var y =
-        new VariableDeclarationJudgment('y', 0, type: new TypeParameterType(U));
-    var method =
-        makeEmptyMethod(typeParameters: [U], positionalParameters: [x, y]);
-    var substitution = Substitution.fromPairs([T], [intType]);
-    var stub = makeForwardingStub(method, false, substitution: substitution);
-    expect(stub.function.positionalParameters[0].type, intType);
-    var stubYType =
-        stub.function.positionalParameters[1].type as TypeParameterType;
-    expect(stubYType.parameter, same(stub.function.typeParameters[0]));
-  }
-
-  void test_createForwardingStub_typeParameter_substituteUses() {
-    // class C { void foo<T>(T x); }
-    var typeParameter = new TypeParameter('T', objectType);
-    var param = new VariableDeclarationJudgment('x', 0,
-        type: new TypeParameterType(typeParameter));
-    var method = makeEmptyMethod(
-        typeParameters: [typeParameter], positionalParameters: [param]);
-    var stub = makeForwardingStub(method, false);
-    var stubXType =
-        stub.function.positionalParameters[0].type as TypeParameterType;
-    expect(stubXType.parameter, same(stub.function.typeParameters[0]));
-  }
-
-  void test_createForwardingStub_typeParameter_substituteUses_fBounded() {
-    // class C { void foo<T extends List<T>>(T x); }
-    var typeParameter = new TypeParameter('T', null);
-    typeParameter.bound =
-        new InterfaceType(listClass, [new TypeParameterType(typeParameter)]);
-    var param = new VariableDeclarationJudgment('x', 0,
-        type: new TypeParameterType(typeParameter));
-    var method = makeEmptyMethod(
-        typeParameters: [typeParameter], positionalParameters: [param]);
-    var stub = makeForwardingStub(method, false);
-    var stubTypeParameter = stub.function.typeParameters[0];
-    var stubTypeParameterBound = stubTypeParameter.bound as InterfaceType;
-    var stubTypeParameterBoundArg =
-        stubTypeParameterBound.typeArguments[0] as TypeParameterType;
-    expect(stubTypeParameterBoundArg.parameter, same(stubTypeParameter));
-    var stubXType =
-        stub.function.positionalParameters[0].type as TypeParameterType;
-    expect(stubXType.parameter, same(stubTypeParameter));
-  }
-
-  void test_direct_isGenericCovariant() {
-    var typeParameter = new TypeParameter('T', objectType);
-    var u = new TypeParameter('U', new TypeParameterType(typeParameter))
-      ..isGenericCovariantImpl = true;
-    var x = new VariableDeclarationJudgment('x', 0,
-        type: new TypeParameterType(typeParameter));
-    var y = new VariableDeclarationJudgment('y', 0,
-        type: new TypeParameterType(typeParameter));
-    var method = makeEmptyMethod(
-        typeParameters: [u], positionalParameters: [x], namedParameters: [y]);
-    var class_ =
-        makeClass(typeParameters: [typeParameter], procedures: [method]);
-    var node = getForwardingNode(class_, false);
-    ShadowClass.setBuilder(class_, null);
-    var resolvedMethod = node.finalize();
-    expect(resolvedMethod, same(method));
-    expect(u.isGenericCovariantImpl, isTrue);
-    expect(x.isGenericCovariantImpl, isTrue);
-    expect(x.isCovariant, isFalse);
-    expect(y.isGenericCovariantImpl, isTrue);
-    expect(y.isCovariant, isFalse);
-  }
-
-  void test_direct_isGenericCovariant_field() {
-    var typeParameter = new TypeParameter('T', objectType);
-    var field = makeField(type: new TypeParameterType(typeParameter));
-    var class_ = makeClass(typeParameters: [typeParameter], fields: [field]);
-    var node = getForwardingNode(class_, true);
-    ShadowClass.setBuilder(class_, null);
-    var resolvedAccessor = node.finalize() as SyntheticAccessor;
-    expect(SyntheticAccessor.getField(resolvedAccessor), same(field));
-    expect(field.isGenericCovariantImpl, isTrue);
-    expect(field.isCovariant, isFalse);
-  }
-
-  void test_field_isCovariant_inherited() {
-    var fieldA = makeField(type: numType)..isCovariant = true;
-    var fieldB = makeField(type: numType);
-    var a = makeClass(name: 'A', fields: [fieldA]);
-    var b = makeClass(
-        name: 'B', implementedTypes: [a.asThisSupertype], fields: [fieldB]);
-    var node = getForwardingNode(b, true);
-    var resolvedAccessor = node.finalize() as SyntheticAccessor;
-    expect(SyntheticAccessor.getField(resolvedAccessor), same(fieldB));
-    expect(fieldB.isGenericCovariantImpl, isFalse);
-    expect(fieldB.isCovariant, isTrue);
-  }
-
-  void test_field_isGenericCovariantImpl_inherited() {
-    var typeParameter = new TypeParameter('T', objectType);
-    var fieldA = makeField(type: new TypeParameterType(typeParameter))
-      ..isGenericCovariantImpl = true;
-    var fieldB = makeField(type: numType);
-    var a =
-        makeClass(name: 'A', typeParameters: [typeParameter], fields: [fieldA]);
-    var b = makeClass(name: 'B', implementedTypes: [
-      new Supertype(a, [numType])
-    ], fields: [
-      fieldB
-    ]);
-    var node = getForwardingNode(b, true);
-    var resolvedAccessor = node.finalize() as SyntheticAccessor;
-    expect(SyntheticAccessor.getField(resolvedAccessor), same(fieldB));
-    expect(fieldB.isGenericCovariantImpl, isTrue);
-    expect(fieldB.isCovariant, isFalse);
-  }
-
-  void test_forwardingNodes_multiple() {
-    var methodAf = makeEmptyMethod(name: 'f');
-    var methodBf = makeEmptyMethod(name: 'f');
-    var methodAg = makeEmptyMethod(name: 'g');
-    var methodBg = makeEmptyMethod(name: 'g');
-    var a = makeClass(name: 'A', procedures: [methodAf, methodAg]);
-    var b = makeClass(
-        name: 'B',
-        supertype: a.asThisSupertype,
-        procedures: [methodBf, methodBg]);
-    var forwardingNodes = getForwardingNodes(b, false);
-    expect(forwardingNodes, hasLength(2));
-    var nodef = ClassHierarchy.findMemberByName(forwardingNodes, methodAf.name);
-    var nodeg = ClassHierarchy.findMemberByName(forwardingNodes, methodAg.name);
-    expect(nodef, isNot(same(nodeg)));
-    expect(nodef.parent, b);
-    expect(nodeg.parent, b);
-    {
-      var candidates = ForwardingNode.getCandidates(nodef);
-      expect(candidates, hasLength(2));
-      expect(candidates[0], same(methodBf));
-      expect(candidates[1], same(methodAf));
-    }
-    {
-      var candidates = ForwardingNode.getCandidates(nodeg);
-      expect(candidates, hasLength(2));
-      expect(candidates[0], same(methodBg));
-      expect(candidates[1], same(methodAg));
-    }
-  }
-
-  void test_forwardingNodes_single() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(
-        name: 'B', supertype: a.asThisSupertype, procedures: [methodB]);
-    var forwardingNodes = getForwardingNodes(b, false);
-    expect(forwardingNodes, hasLength(1));
-    expect(forwardingNodes[0].parent, b);
-    expect(forwardingNodes[0].name, methodA.name);
-    var candidates = ForwardingNode.getCandidates(forwardingNodes[0]);
-    expect(candidates, hasLength(2));
-    expect(candidates[0], same(methodB));
-    expect(candidates[1], same(methodA));
-  }
-
-  void test_forwardingStub_isCovariant_inherited() {
-    var methodA = makeEmptyMethod(positionalParameters: [
-      new VariableDeclarationJudgment('x', 0, type: numType)
-    ], namedParameters: [
-      new VariableDeclarationJudgment('y', 0, type: numType)
-    ]);
-    var methodB = makeEmptyMethod(positionalParameters: [
-      new VariableDeclarationJudgment('x', 0, type: intType)..isCovariant = true
-    ], namedParameters: [
-      new VariableDeclarationJudgment('y', 0, type: intType)..isCovariant = true
-    ]);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C',
-        supertype: a.asThisSupertype,
-        implementedTypes: [b.asThisSupertype]);
-    var node = getForwardingNode(c, false);
-    var stub = node.finalize();
-    var x = stub.function.positionalParameters[0];
-    expect(x.isGenericCovariantImpl, isFalse);
-    expect(x.isCovariant, isTrue);
-    var y = stub.function.namedParameters[0];
-    expect(y.isGenericCovariantImpl, isFalse);
-    expect(y.isCovariant, isTrue);
-    expect(stub.forwardingStubInterfaceTarget, same(methodA));
-    expect(getStubTarget(stub), same(methodA));
-  }
-
-  void test_forwardingStub_isGenericCovariantImpl_inherited() {
-    var methodA = makeEmptyMethod(typeParameters: [
-      new TypeParameter('U', numType)
-    ], positionalParameters: [
-      new VariableDeclarationJudgment('x', 0, type: numType)
-    ], namedParameters: [
-      new VariableDeclarationJudgment('y', 0, type: numType)
-    ]);
-    var typeParameterB = new TypeParameter('T', objectType);
-    var methodB = makeEmptyMethod(typeParameters: [
-      new TypeParameter('U', new TypeParameterType(typeParameterB))
-        ..isGenericCovariantImpl = true
-    ], positionalParameters: [
-      new VariableDeclarationJudgment('x', 0,
-          type: new TypeParameterType(typeParameterB))
-        ..isGenericCovariantImpl = true
-    ], namedParameters: [
-      new VariableDeclarationJudgment('y', 0,
-          type: new TypeParameterType(typeParameterB))
-        ..isGenericCovariantImpl = true
-    ]);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(
-        name: 'B', typeParameters: [typeParameterB], procedures: [methodB]);
-    var c =
-        makeClass(name: 'C', supertype: a.asThisSupertype, implementedTypes: [
-      new Supertype(b, [numType])
-    ]);
-    var node = getForwardingNode(c, false);
-    var stub = node.finalize();
-    var u = stub.function.typeParameters[0];
-    expect(u.isGenericCovariantImpl, isTrue);
-    var x = stub.function.positionalParameters[0];
-    expect(x.isGenericCovariantImpl, isTrue);
-    expect(x.isCovariant, isFalse);
-    var y = stub.function.namedParameters[0];
-    expect(y.isGenericCovariantImpl, isTrue);
-    expect(y.isCovariant, isFalse);
-    expect(stub.forwardingStubInterfaceTarget, same(methodA));
-    expect(getStubTarget(stub), same(methodA));
-  }
-
-  void test_interfaceTarget_cascaded() {
-    var methodC = makeEmptyMethod(positionalParameters: [
-      new VariableDeclaration('x', type: intType),
-      new VariableDeclaration('y', type: intType)
-    ]);
-    var c = makeClass(name: 'C', procedures: [methodC]);
-    var t = new TypeParameter('T', objectType);
-    var methodI1 = makeEmptyMethod(positionalParameters: [
-      new VariableDeclaration('x', type: new TypeParameterType(t))
-        ..isGenericCovariantImpl = true,
-      new VariableDeclaration('y', type: intType)
-    ]);
-    var i1 = makeClass(name: 'I1', typeParameters: [t], procedures: [methodI1]);
-    // Let's say D was previously compiled, so it already has a forwarding stub
-    var d =
-        makeClass(name: 'D', supertype: c.asThisSupertype, implementedTypes: [
-      new Supertype(i1, [intType])
-    ]);
-    var nodeD = getForwardingNode(d, false);
-    var methodD = ForwardingNode.createForwardingStubForTesting(
-        nodeD, Substitution.empty, methodC);
-    d.addMember(methodD);
-    ForwardingNode.createForwardingImplIfNeededForTesting(
-        nodeD, methodD.function);
-    // To ensure that we don't accidentally make use of information that was
-    // computed prior to adding the forwarding stub, reset the interface
-    // resolver.
-    resetInterfaceResolver();
-    var u = new TypeParameter('U', objectType);
-    var methodI2 = makeEmptyMethod(positionalParameters: [
-      new VariableDeclaration('x', type: intType),
-      new VariableDeclaration('y', type: new TypeParameterType(u))
-        ..isGenericCovariantImpl = true
-    ]);
-    var i2 = makeClass(name: 'I2', typeParameters: [u], procedures: [methodI2]);
-    var e =
-        makeClass(name: 'E', supertype: d.asThisSupertype, implementedTypes: [
-      new Supertype(i2, [intType])
-    ]);
-    var nodeE = getForwardingNode(e, false);
-    var stub = nodeE.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(methodC));
-    expect(getStubTarget(stub), same(methodC));
-  }
-
-  void test_interfaceTarget_cascaded_setter() {
-    var setterC = makeSetter(setterType: intType);
-    var c = makeClass(name: 'C', procedures: [setterC]);
-    var t = new TypeParameter('T', objectType);
-    var setterI1 = makeSetter(setterType: new TypeParameterType(t));
-    var i1 = makeClass(name: 'I1', typeParameters: [t], procedures: [setterI1]);
-    // Let's say D was previously compiled, so it already has a forwarding stub
-    var d =
-        makeClass(name: 'D', supertype: c.asThisSupertype, implementedTypes: [
-      new Supertype(i1, [intType])
-    ]);
-    var nodeD = getForwardingNode(d, true);
-    var setterD = ForwardingNode.createForwardingStubForTesting(
-        nodeD, Substitution.empty, setterC);
-    d.addMember(setterD);
-    ForwardingNode.createForwardingImplIfNeededForTesting(
-        nodeD, setterD.function);
-    // To ensure that we don't accidentally make use of information that was
-    // computed prior to adding the forwarding stub, reset the interface
-    // resolver.
-    resetInterfaceResolver();
-    var setterI2 = makeSetter(setterType: intType, isCovariant: true);
-    var i2 = makeClass(name: 'I2', procedures: [setterI2]);
-    var e = makeClass(
-        name: 'E',
-        supertype: d.asThisSupertype,
-        implementedTypes: [i2.asThisSupertype]);
-    var nodeE = getForwardingNode(e, true);
-    var stub = nodeE.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(setterC));
-    expect(getStubTarget(stub), same(setterC));
-  }
-
-  void test_interfaceTarget_field() {
-    var fieldA = makeField(type: numType, isFinal: true);
-    var fieldB = makeField(type: intType, isFinal: true);
-    var a = makeClass(name: 'A', fields: [fieldA]);
-    var b = makeClass(name: 'B', fields: [fieldB]);
-    var c = makeClass(
-        name: 'C',
-        supertype: a.asThisSupertype,
-        implementedTypes: [b.asThisSupertype]);
-    var node = getForwardingNode(c, false);
-    var stub = node.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(fieldB));
-  }
-
-  void test_merge_candidates_including_mixin() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var methodC = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(name: 'C', procedures: [methodC]);
-    var d = makeClass(
-        name: 'D',
-        supertype: a.asThisSupertype,
-        mixedInType: b.asThisSupertype,
-        implementedTypes: [c.asThisSupertype]);
-    var candidates = getCandidates(d, false);
-    expect(candidates, hasLength(3));
-    expect(candidates[0], same(methodB));
-    expect(candidates[1], same(methodA));
-    expect(candidates[2], same(methodC));
-  }
-
-  void test_merge_candidates_not_including_mixin() {
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var methodC = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C',
-        supertype: a.asThisSupertype,
-        implementedTypes: [b.asThisSupertype],
-        procedures: [methodC]);
-    var candidates = getCandidates(c, false);
-    expect(candidates, hasLength(3));
-    expect(candidates[0], same(methodC));
-    expect(candidates[1], same(methodA));
-    expect(candidates[2], same(methodB));
-  }
-
-  void test_resolve_directly_declared() {
-    var parameterA = new VariableDeclarationJudgment('x', 0,
-        type: objectType, isCovariant: true);
-    var methodA = makeEmptyMethod(positionalParameters: [parameterA]);
-    var parameterB = new VariableDeclarationJudgment('x', 0,
-        type: intType, isCovariant: true);
-    var methodB = makeEmptyMethod(positionalParameters: [parameterB]);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(
-        name: 'B', supertype: a.asThisSupertype, procedures: [methodB]);
-    var node = getForwardingNode(b, false);
-    expect(node.finalize(), same(methodB));
-  }
-
-  void test_resolve_favor_first() {
-    // When multiple methods have equivalent types, favor the first one.
-    var methodA = makeEmptyMethod();
-    var methodB = makeEmptyMethod();
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
-    var node = getForwardingNode(c, false);
-    expect(node.finalize(), same(methodA));
-  }
-
-  void test_resolve_field() {
-    var field = makeField();
-    var a = makeClass(name: 'A', fields: [field]);
-    var b = makeClass(name: 'B', supertype: a.asThisSupertype);
-    var node = getForwardingNode(b, false);
-    var accessor = node.finalize() as SyntheticAccessor;
-    expect(SyntheticAccessor.getField(accessor), same(field));
-  }
-
-  void test_resolve_first() {
-    var methodA = makeEmptyMethod(returnType: intType);
-    var methodB = makeEmptyMethod(returnType: numType);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
-    var node = getForwardingNode(c, false);
-    expect(node.finalize(), same(methodA));
-  }
-
-  void test_resolve_second() {
-    var methodA = makeEmptyMethod(returnType: numType);
-    var methodB = makeEmptyMethod(returnType: intType);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(name: 'B', procedures: [methodB]);
-    var c = makeClass(
-        name: 'C', implementedTypes: [a.asThisSupertype, b.asThisSupertype]);
-    var node = getForwardingNode(c, false);
-    var stub = node.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(methodB));
-    expect(getStubTarget(stub), isNull);
-    expect(stub.function.returnType, intType);
-  }
-
-  void test_resolve_setters() {
-    var setterA = makeSetter(setterType: intType);
-    var setterB = makeSetter(setterType: objectType);
-    var setterC = makeSetter(setterType: numType);
-    var a = makeClass(name: 'A', procedures: [setterA]);
-    var b = makeClass(name: 'B', procedures: [setterB]);
-    var c = makeClass(name: 'C', procedures: [setterC]);
-    var d = makeClass(name: 'D', implementedTypes: [
-      a.asThisSupertype,
-      b.asThisSupertype,
-      c.asThisSupertype
-    ]);
-    var node = getForwardingNode(d, true);
-    var stub = node.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(setterB));
-    expect(getStubTarget(stub), isNull);
-    expect(stub.function.positionalParameters[0].type, objectType);
-  }
-
-  void test_resolve_with_added_implementation() {
-    var methodA = makeEmptyMethod(positionalParameters: [
-      new VariableDeclarationJudgment('x', 0, type: numType)
-    ]);
-    var typeParamB = new TypeParameter('T', objectType);
-    var methodB = makeEmptyMethod(positionalParameters: [
-      new VariableDeclarationJudgment('x', 0,
-          type: new TypeParameterType(typeParamB))
-        ..isGenericCovariantImpl = true
-    ]);
-    var methodC = makeEmptyMethod(positionalParameters: [
-      new VariableDeclarationJudgment('x', 0, type: numType)
-    ], isAbstract: true);
-    var a = makeClass(name: 'A', procedures: [methodA]);
-    var b = makeClass(
-        name: 'B', typeParameters: [typeParamB], procedures: [methodB]);
-    var c =
-        makeClass(name: 'C', supertype: a.asThisSupertype, implementedTypes: [
-      new Supertype(b, [numType])
-    ], procedures: [
-      methodC
-    ]);
-    var node = getForwardingNode(c, false);
-    expect(methodC.function.body, isNull);
-    var resolvedMethod = node.finalize();
-    expect(resolvedMethod, same(methodC));
-    expect(methodC.function.body, isNotNull);
-    expect(methodC.forwardingStubInterfaceTarget, isNull);
-    expect(getStubTarget(methodC), same(methodA));
-  }
-
-  void test_resolve_with_substitutions() {
-    var typeParamA = new TypeParameter('T', objectType);
-    var typeParamB = new TypeParameter('T', objectType);
-    var typeParamC = new TypeParameter('T', objectType);
-    var methodA =
-        makeEmptyMethod(returnType: new TypeParameterType(typeParamA));
-    var methodB =
-        makeEmptyMethod(returnType: new TypeParameterType(typeParamB));
-    var methodC =
-        makeEmptyMethod(returnType: new TypeParameterType(typeParamC));
-    var a = makeClass(
-        name: 'A', typeParameters: [typeParamA], procedures: [methodA]);
-    var b = makeClass(
-        name: 'B', typeParameters: [typeParamB], procedures: [methodB]);
-    var c = makeClass(
-        name: 'C', typeParameters: [typeParamC], procedures: [methodC]);
-    var d = makeClass(
-        name: 'D',
-        supertype: new Supertype(a, [objectType]),
-        implementedTypes: [
-          new Supertype(b, [intType]),
-          new Supertype(c, [numType])
-        ]);
-    var node = getForwardingNode(d, false);
-    var stub = node.finalize();
-    expect(stub.forwardingStubInterfaceTarget, same(methodB));
-    expect(getStubTarget(stub), isNull);
-    expect(stub.function.returnType, intType);
-  }
-}
diff --git a/pkg/front_end/testcases/ignore_function.dart b/pkg/front_end/testcases/ignore_function.dart
new file mode 100644
index 0000000..83c33eb
--- /dev/null
+++ b/pkg/front_end/testcases/ignore_function.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:core" as core;
+
+class A implements core.Function {
+  // No error here: core.Function is ignored.
+  operator ==(other) => false;
+}
+
+class B implements Function {
+  // Error here Object.== and Function.== disagree on the type of other.
+  operator ==(other) => false;
+}
+
+class Function {
+  core.bool operator ==(core.Object other) => false;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart
index b63fb9a..69efb53 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart
@@ -5,7 +5,7 @@
 /*@testedFeatures=inference*/
 library test;
 
-var x = /*@returnType=invalid-type*/ () => y;
+var x = /*@returnType=() -> invalid-type*/ () => y;
 var y = /*@returnType=invalid-type*/ () => x;
 
 main() {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart
index b63fb9a..69efb53 100644
--- a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart
@@ -5,7 +5,7 @@
 /*@testedFeatures=inference*/
 library test;
 
-var x = /*@returnType=invalid-type*/ () => y;
+var x = /*@returnType=() -> invalid-type*/ () => y;
 var y = /*@returnType=invalid-type*/ () => x;
 
 main() {}
diff --git a/pkg/front_end/testcases/inference/conflicting_fields.dart b/pkg/front_end/testcases/inference/conflicting_fields.dart
index 72edc67..8dacd55 100644
--- a/pkg/front_end/testcases/inference/conflicting_fields.dart
+++ b/pkg/front_end/testcases/inference/conflicting_fields.dart
@@ -17,6 +17,8 @@
 class B extends A implements I {
   get field1 => null;
   get field2 => null;
+  set field1(value) {}
+  set field2(value) {}
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/inference/inconsistent_overrides.dart b/pkg/front_end/testcases/inference/inconsistent_overrides.dart
new file mode 100644
index 0000000..9030aea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inconsistent_overrides.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test;
+
+/*@testedFeatures=inference*/
+
+class A {
+  A f(A x, {A y}) {}
+  A g(A x, {A y}) {}
+  A h(A x, {A y}) {}
+}
+
+class B extends A implements I {
+  f(x, {y}) {}
+  g(x, {y}) {}
+  h(x, {y}) {}
+}
+
+class I {
+  I f(I x, {I y}) {}
+  A g(I x, {I y}) {}
+  A h(A x, {I y}) {}
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
index 5d9af14..cf441f7 100644
--- a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart
@@ -15,8 +15,8 @@
 // There's a circularity between b and c because a.f is generic, so the type of
 // c is required to infer b, and vice versa.
 
-var b = /*@returnType=invalid-type*/ () =>
-    a. /*@typeArgs=invalid-type*/ /*@target=A::f*/ f(c);
+var b = /*@returnType=() -> invalid-type*/ () =>
+    a. /*@typeArgs=() -> invalid-type*/ /*@target=A::f*/ f(c);
 var c = /*@returnType=invalid-type*/ () =>
     a. /*@typeArgs=invalid-type*/ /*@target=A::f*/ f(b);
 
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart
new file mode 100644
index 0000000..d6f3096
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_accessors.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class A {
+  A get x;
+  void set x(B value);
+
+  B get y;
+  void set y(A value);
+}
+
+abstract class B extends A {}
+
+class C extends B {
+  var x;
+  var y;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
index 9ffd8ea..f24c3f1 100644
--- a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart
@@ -8,12 +8,12 @@
 // In the code below, there is a circularity between A.b and x.
 
 class A {
-  var b = /*@returnType=invalid-type*/ () => x;
-  var c = /*@returnType=invalid-type*/ () => x;
+  var b = /*@returnType=() -> invalid-type*/ () => x;
+  var c = /*@returnType=() -> invalid-type*/ () => x;
 }
 
 var a = new A();
 var x = /*@returnType=invalid-type*/ () => a. /*@target=A::b*/ b;
-var y = /*@returnType=() -> invalid-type*/ () => a. /*@target=A::c*/ c;
+var y = /*@returnType=() -> () -> invalid-type*/ () => a. /*@target=A::c*/ c;
 
 main() {}
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart
index 788e92f..d378992 100644
--- a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart
@@ -14,7 +14,7 @@
 // circularity, and for error recovery their type is set to `dynamic`.
 // Thereafter, z infers without problems.
 
-var x = /*@returnType=invalid-type*/ () => f() ? y : z;
+var x = /*@returnType=() -> invalid-type*/ () => f() ? y : z;
 var y = /*@returnType=invalid-type*/ () => x;
 var z = /*@returnType=invalid-type*/ () => x;
 
diff --git a/pkg/front_end/testcases/issue129167943.dart b/pkg/front_end/testcases/issue129167943.dart
new file mode 100644
index 0000000..c7560ea
--- /dev/null
+++ b/pkg/front_end/testcases/issue129167943.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class A {}
+
+abstract class B {
+  void foo(num x);
+}
+
+abstract class C implements B {
+  void foo(covariant int x);
+}
+
+abstract class D1 implements A, C, B {
+  void foo(covariant int x);
+}
+
+class D2 implements A, C, B {
+  void foo(covariant int x) {}
+}
+
+abstract class D3 implements A, C, B {}
+
+abstract class D4 implements A, C, B {
+  void foo(int x);
+}
+
+abstract class D5 implements A, C, B {
+  void foo(num x);
+}
+
+abstract class E {
+  void set foo(num x);
+}
+
+abstract class G implements E {
+  void set foo(covariant int x);
+}
+
+abstract class H1 implements A, E, G {
+  void set foo(covariant int x);
+}
+
+class H2 implements A, E, G {
+  void set foo(covariant int x) {}
+}
+
+abstract class H3 implements A, E, G {}
+
+abstract class H4 implements A, E, G {
+  void set foo(int x);
+}
+
+abstract class H5 implements A, E, G {
+  void set foo(num x);
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
index 4b4ea07..47824ee 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
@@ -14,7 +14,7 @@
 }
 
 class C extends B implements I<num> {
-  void /*@forwardingStub=semi-stub*/ f(num x);
+  void f(num x);
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index c42599d..e6e64b1 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -107,6 +107,7 @@
 hello: TextSerializationFailure # Was: Pass
 having_part_with_part_and_annotation: TextSerializationFailure
 having_part_with_parts_and_annotation: TextSerializationFailure
+ignore_function: TypeCheckError
 illegal_named_function_expression: TextSerializationFailure # Was: Pass
 illegal_named_function_expression_scope: TextSerializationFailure # Was: Pass
 implicit_const_with_static_fields: TextSerializationFailure # Was: Pass
@@ -163,6 +164,7 @@
 inference/complex_predecrement: TextSerializationFailure # Was: Pass
 inference/conditional_lub: TextSerializationFailure # Was: Pass
 inference/conditional_upwards_inference: TextSerializationFailure # Was: Pass
+inference/conflicting_fields: ExpectationFileMismatch
 inference/conflicting_fields: TypeCheckError
 inference/conflicts_can_happen2: TypeCheckError
 inference/conflicts_can_happen: TypeCheckError
@@ -278,6 +280,7 @@
 inference/generic_methods_nested_generic_instantiation: TextSerializationFailure # Was: Pass
 inference/generic_methods_uses_greatest_lower_bound: TextSerializationFailure # Was: Pass
 inference/greatest_closure_multiple_params: TextSerializationFailure # Was: Pass
+inference/inconsistent_overrides: TypeCheckError
 inference/index_assign_operator_return_type: TextSerializationFailure # Was: Pass
 inference/index_assign_operator_return_type_2: TextSerializationFailure # Was: Pass
 inference/infer_accessor_from_later_inferred_field: TextSerializationFailure # Was: Pass
@@ -341,6 +344,7 @@
 inference/infer_local_function_referenced_before_declaration: TextSerializationFailure # Was: Pass
 inference/infer_local_function_return_type: TextSerializationFailure # Was: Pass
 inference/infer_method_function_typed: TextSerializationFailure # Was: Pass
+inference/infer_method_missing_params: ExpectationFileMismatch
 inference/infer_method_missing_params: TypeCheckError
 inference/infer_parameter_type_setter_from_field: TextSerializationFailure # Was: Pass
 inference/infer_parameter_type_setter_from_setter: TextSerializationFailure # Was: Pass
@@ -587,6 +591,7 @@
 inference_new/infer_assign_to_static: TextSerializationFailure # Was: Pass
 inference_new/infer_assign_to_static_upwards: TextSerializationFailure # Was: Pass
 inference_new/infer_field_getter_setter_mismatch: TypeCheckError
+inference_new/infer_field_override_accessors: TypeCheckError
 inference_new/infer_field_override_getter_overrides_setter: TypeCheckError
 inference_new/infer_field_override_setter_overrides_getter: TextSerializationFailure # Was: Pass
 inference_new/infer_instance_accessor_ref: TextSerializationFailure # Was: Pass
@@ -606,6 +611,7 @@
 inference_new/super_index_get: TextSerializationFailure # Was: Pass
 inference_new/super_index_get_substitution: TextSerializationFailure # Was: Pass
 inference_new/switch: TextSerializationFailure # Was: Pass
+inference_new/top_level_field_depends_on_multiple_inheritance: ExpectationFileMismatch
 inference_new/top_level_field_depends_on_multiple_inheritance: TextSerializationFailure # Was: Pass
 inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2: TextSerializationFailure # Was: Pass
 inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2: TextSerializationFailure # Was: Pass
@@ -681,6 +687,7 @@
 invalid_cast: TextSerializationFailure # Was: Pass
 invalid_type: TypeCheckError
 invocations: TextSerializationFailure # Was: RuntimeError
+issue129167943: TextSerializationFailure
 issue34515: TextSerializationFailure
 issue34899: TypeCheckError
 issue35875: TextSerializationFailure
@@ -696,6 +703,7 @@
 minimum_int: TextSerializationFailure # Was: Pass
 missing_constructor: TextSerializationFailure # Was: Pass
 mixin: TextSerializationFailure # Was: Pass
+mixin_application_override: ExpectationFileMismatch
 mixin_application_override: TypeCheckError
 mixin_conflicts: TextSerializationFailure
 mixin_constructors_with_default_values: TextSerializationFailure # Was: Pass
@@ -967,6 +975,7 @@
 runtime_checks/dynamic_invocation: TextSerializationFailure # Was: Pass
 runtime_checks/dynamic_invocation_generic: TextSerializationFailure # Was: Pass
 runtime_checks/dynamic_invocation_of_getter: TextSerializationFailure # Was: Pass
+runtime_checks/field_forwarding_stub_generic_covariant: ExpectationFileMismatch
 runtime_checks/field_forwarding_stub_generic_covariant: TextSerializationFailure # Was: Pass
 runtime_checks/forwarding_stub_with_default_values: TextSerializationFailure # Was: Pass
 runtime_checks/forwarding_stub_with_non_covariant_param: TextSerializationFailure # Was: Pass
@@ -980,6 +989,7 @@
 runtime_checks/implicit_downcast_if: TextSerializationFailure # Was: Pass
 runtime_checks/implicit_downcast_not: TextSerializationFailure # Was: Pass
 runtime_checks/implicit_downcast_while: TextSerializationFailure # Was: Pass
+runtime_checks_new/abstract_override_becomes_forwarding_stub: ExpectationFileMismatch
 runtime_checks_new/abstract_override_becomes_forwarding_stub: TextSerializationFailure # Was: Pass
 runtime_checks_new/call_through_this: TextSerializationFailure # Was: Pass
 runtime_checks_new/contravariant_combiner: TextSerializationFailure # Was: Pass
@@ -989,12 +999,15 @@
 runtime_checks_new/contravariant_index_get: TextSerializationFailure # Was: Pass
 runtime_checks_new/derived_class_typed: TextSerializationFailure # Was: Pass
 runtime_checks_new/field_forwarding_stub_abstract_generic_covariant: TextSerializationFailure # Was: Pass
+runtime_checks_new/field_forwarding_stub_explicit_covariant: ExpectationFileMismatch
 runtime_checks_new/field_forwarding_stub_explicit_covariant: TextSerializationFailure # Was: Pass
 runtime_checks_new/for_in_call_kinds: TextSerializationFailure # Was: Pass
 runtime_checks_new/generic_covariance_based_on_inference: TextSerializationFailure # Was: Pass
 runtime_checks_new/implicit_downcast_field: TextSerializationFailure # Was: Pass
+runtime_checks_new/mixin_forwarding_stub_field: ExpectationFileMismatch
 runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
 runtime_checks_new/mixin_forwarding_stub_getter: TypeCheckError
+runtime_checks_new/mixin_forwarding_stub_setter: ExpectationFileMismatch
 runtime_checks_new/mixin_forwarding_stub_setter: TypeCheckError
 runtime_checks_new/stub_checked_via_target: TextSerializationFailure # Was: Pass
 runtime_checks_new/stub_from_interface_contravariant_from_class: TextSerializationFailure # Was: Pass
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 474f907..ed156b1 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -247,14 +247,14 @@
   /// Compares members by name, using the same sort order as
   /// [getDeclaredMembers] and [getInterfaceMembers].
   static int compareMembers(Member first, Member second) {
-    return _compareNames(first.name, second.name);
+    return compareNames(first.name, second.name);
   }
 
   /// Compares names, using the same sort order as [getDeclaredMembers] and
   /// [getInterfaceMembers].
   ///
   /// This is an arbitrary as-fast-as-possible sorting criterion.
-  static int _compareNames(Name firstName, Name secondName) {
+  static int compareNames(Name firstName, Name secondName) {
     int firstHash = firstName.hashCode;
     int secondHash = secondName.hashCode;
     if (firstHash != secondHash) return firstHash - secondHash;
@@ -291,7 +291,7 @@
     while (low <= high) {
       int mid = low + ((high - low) >> 1);
       Member pivot = members[mid];
-      int comparison = _compareNames(name, pivot.name);
+      int comparison = compareNames(name, pivot.name);
       if (comparison < 0) {
         high = mid - 1;
       } else if (comparison > 0) {
