anchor.diff:      }
       Declaration result = a;
       if (mergeKind == MergeKind.interfaces) {
  -      // TODO(ahe): Combine the signatures of a and b.
  +      // 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 (aTarget.isAbstract) {
         if (mergeKind == MergeKind.superclass && !bTarget.isAbstract) {
           // An abstract method doesn't override an implemention inherited from a
  
positive.code:       // Don't check overrides involving duplicated members.
        return a;
      }
      Member aTarget = a.target;
      Member bTarget = b.target;
      if ((memberKind(aTarget) ?? ProcedureKind.Getter) !=
          (memberKind(bTarget) ?? ProcedureKind.Getter)) {
        String name = a.fullNameForErrors;
        if (mergeKind == MergeKind.interfaces) {
          cls.addProblem(messageInheritedMembersConflict, cls.charOffset,
  
negative.code:   return !name.isPrivate || name.library == library.target;
  }
  
  /// Returns true if [a] is a class member conflict with [b].  [a] is assumed to
  /// be declared in the class, [b] is assumed to be inherited.
  ///
  /// See the section named "Class Member Conflicts" in [Dart Programming
  /// Language Specification](
  /// ../../../../../../docs/language/dartLangSpec.tex#classMemberConflicts).
  bool isInheritanceConflict(Declaration a, Declaration b) {
    if (a.isField) return !(b.isField || b.isGetter || b.isSetter);
    if (b.isField) return !(a.isField || a.isGetter || a.isSetter);
    return memberKind(a.target) != memberKind(b.target);
  }
  
  class ClassHierarchyBuilder {
    final Map<KernelClassBuilder, ClassHierarchyNode> nodes =
        <KernelClassBuilder, ClassHierarchyNode>{};
  