anchor.diff:    }
   }
   
  -/**
  - * Base class for testing LUB and GLB in spec and strong mode.
  - */
  -abstract class BoundTestBase {
  -  TypeProvider typeProvider;
  -  Dart2TypeSystem typeSystem;
  -  FunctionType simpleFunctionType;
  -
  -  DartType get bottomType => typeProvider.bottomType;
  -  InterfaceType get doubleType => typeProvider.doubleType;
  -  DartType get dynamicType => typeProvider.dynamicType;
  -  InterfaceType get functionType => typeProvider.functionType;
  -  InterfaceType get futureOrType => typeProvider.futureOrType;
  -  InterfaceType get intType => typeProvider.intType;
  -  InterfaceType get iterableType => typeProvider.iterableType;
  -  InterfaceType get listType => typeProvider.listType;
  -  InterfaceType get nullType => typeProvider.nullType;
  -  InterfaceType get numType => typeProvider.numType;
  -  InterfaceType get objectType => typeProvider.objectType;
  -  InterfaceType get stringType => typeProvider.stringType;
  -
  -  DartType get voidType => VoidTypeImpl.instance;
  -
  -  void setUp() {
  -    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore(
  -        resourceProvider: new MemoryResourceProvider());
  -    typeProvider = context.typeProvider;
  -    var simpleFunctionElement =
  -        ElementFactory.genericTypeAliasElement('A', returnType: voidType);
  -    simpleFunctionType = simpleFunctionElement.type;
  -  }
  -
  -  void _checkGreatestLowerBound(
  -      DartType type1, DartType type2, DartType expectedResult) {
  -    DartType glb = typeSystem.getGreatestLowerBound(type1, type2);
  -    expect(glb, expectedResult);
  -    // Check that the result is a lower bound.
  -    expect(typeSystem.isSubtypeOf(glb, type1), true);
  -    expect(typeSystem.isSubtypeOf(glb, type2), true);
  -    // Check for symmetry while we're at it.  Unfortunately,
  -    // for function types, the current version of equality
  -    // does not respect re-ordering of named parameters, so
  -    // for function types we just check if they are mutual subtypes.
  -    // https://github.com/dart-lang/sdk/issues/26126
  -    // TODO(leafp): Fix this.
  -    glb = typeSystem.getGreatestLowerBound(type2, type1);
  -    if (glb is FunctionTypeImpl) {
  -      expect(typeSystem.isSubtypeOf(glb, expectedResult), true);
  -      expect(typeSystem.isSubtypeOf(expectedResult, glb), true);
  -    } else {
  -      expect(glb, expectedResult);
  -    }
  -  }
  -
  -  void _checkLeastUpperBound(
  -      DartType type1, DartType type2, DartType expectedResult) {
  -    DartType lub = typeSystem.getLeastUpperBound(type1, type2);
  -    expect(lub, expectedResult);
  -    // Check that the result is an upper bound.
  -    expect(typeSystem.isSubtypeOf(type1, lub), true);
  -    expect(typeSystem.isSubtypeOf(type2, lub), true);
  -
  -    // Check for symmetry while we're at it.  Unfortunately,
  -    // for function types, the current version of equality
  -    // does not respect re-ordering of named parameters, so
  -    // for function types we just check if they are mutual subtypes.
  -    // https://github.com/dart-lang/sdk/issues/26126
  -    // TODO(leafp): Fix this.
  -    lub = typeSystem.getLeastUpperBound(type2, type1);
  -    if (lub is FunctionTypeImpl) {
  -      expect(typeSystem.isSubtypeOf(lub, expectedResult), true);
  -      expect(typeSystem.isSubtypeOf(expectedResult, lub), true);
  -    } else {
  -      expect(lub, expectedResult);
  -    }
  -  }
  -
  -  /**
  -   * Creates a function type with the given parameter and return types.
  -   *
  -   * The return type defaults to `void` if omitted.
  -   */
  -  FunctionType _functionType(List<DartType> required,
  -      {List<DartType> optional,
  -      Map<String, DartType> named,
  -      DartType returns}) {
  -    if (returns == null) {
  -      returns = voidType;
  -    }
  -
  -    return ElementFactory.functionElement8(required, returns,
  -            optional: optional, named: named)
  -        .type;
  -  }
  -}
  -
   @reflectiveTest
  -class ConstraintMatchingTest {
  -  TypeProvider typeProvider;
  -  TypeSystem typeSystem;
  -  TypeParameterType T;
  -
  -  DartType get dynamicType => DynamicTypeImpl.instance;
  -
  -  InterfaceType get functionType => typeProvider.functionType;
  -
  -  InterfaceType get intType => typeProvider.intType;
  -
  -  InterfaceType get nullType => typeProvider.nullType;
  -
  -  InterfaceType get objectType => typeProvider.objectType;
  -
  -  InterfaceType get stringType => typeProvider.stringType;
  -
  -  DartType get voidType => VoidTypeImpl.instance;
  -
  -  DartType fn(DartType paramType, DartType returnType) =>
  -      new FunctionElementImpl.synthetic([
  -        new ParameterElementImpl.synthetic(
  -            'value', paramType, ParameterKind.REQUIRED)
  -      ], returnType)
  -          .type;
  -
  -  DartType future(DartType T) => typeProvider.futureType.instantiate([T]);
  -
  -  DartType futureOr(DartType T) => typeProvider.futureOrType.instantiate([T]);
  -
  -  DartType iterable(DartType T) => typeProvider.iterableType.instantiate([T]);
  -
  -  DartType list(DartType T) => typeProvider.listType.instantiate([T]);
  -
  -  void setUp() {
  -    typeProvider = AnalysisContextFactory.contextWithCore(
  -            resourceProvider: new MemoryResourceProvider())
  -        .typeProvider;
  -    typeSystem = new Dart2TypeSystem(typeProvider);
  -    T = _newTypeParameter('T');
  -  }
  -
  -  void test_function_coreFunction() {
  -    _checkOrdinarySubtypeMatch(fn(intType, stringType), functionType, [T],
  -        covariant: true);
  -  }
  -
  -  void test_function_parameter_types() {
  -    _checkIsSubtypeMatchOf(
  -        fn(T, intType), fn(stringType, intType), [T], ['String <: T'],
  -        covariant: true);
  -  }
  -
  -  void test_function_return_types() {
  -    _checkIsSubtypeMatchOf(
  -        fn(intType, T), fn(intType, stringType), [T], ['T <: String'],
  -        covariant: true);
  -  }
  -
  -  void test_futureOr_futureOr() {
  -    _checkIsSubtypeMatchOf(
  -        futureOr(T), futureOr(stringType), [T], ['T <: String'],
  -        covariant: true);
  -  }
  -
  -  void test_futureOr_x_fail_future_branch() {
  -    // FutureOr<List<T>> <: List<String> can't be satisfied because
  -    // Future<List<T>> <: List<String> can't be satisfied
  -    _checkIsNotSubtypeMatchOf(futureOr(list(T)), list(stringType), [T],
  -        covariant: true);
  -  }
  -
  -  void test_futureOr_x_fail_nonFuture_branch() {
  -    // FutureOr<List<T>> <: Future<List<String>> can't be satisfied because
  -    // List<T> <: Future<List<String>> can't be satisfied
  -    _checkIsNotSubtypeMatchOf(futureOr(list(T)), future(list(stringType)), [T],
  -        covariant: true);
  -  }
  -
  -  void test_futureOr_x_success() {
  -    // FutureOr<T> <: Future<T> can be satisfied by T=Null.  At this point in
  -    // the type inference algorithm all we figure out is that T must be a
  -    // subtype of both String and Future<String>.
  -    _checkIsSubtypeMatchOf(futureOr(T), future(stringType), [T],
  -        ['T <: String', 'T <: Future<String>'],
  -        covariant: true);
  -  }
  -
  -  void test_lhs_null() {
  -    // Null <: T is trivially satisfied by the constraint Null <: T.
  -    _checkIsSubtypeMatchOf(nullType, T, [T], ['Null <: T'], covariant: false);
  -    // For any other type X, Null <: X is satisfied without the need for any
  -    // constraints.
  -    _checkOrdinarySubtypeMatch(nullType, list(T), [T], covariant: false);
  -    _checkOrdinarySubtypeMatch(nullType, stringType, [T], covariant: false);
  -    _checkOrdinarySubtypeMatch(nullType, voidType, [T], covariant: false);
  -    _checkOrdinarySubtypeMatch(nullType, dynamicType, [T], covariant: false);
  -    _checkOrdinarySubtypeMatch(nullType, objectType, [T], covariant: false);
  -    _checkOrdinarySubtypeMatch(nullType, nullType, [T], covariant: false);
  -    _checkOrdinarySubtypeMatch(nullType, fn(intType, stringType), [T],
  -        covariant: false);
  -  }
  -
  -  void test_param_on_lhs_contravariant_direct() {
  -    // When doing a contravariant match, the type parameters we're trying to
  -    // find types for are on the right hand side.  Is a type parameter also
  -    // appears on the left hand side, there is a condition in which the
  -    // constraint can be satisfied without consulting the bound of the LHS type
  -    // parameter: the condition where both parameters appear at corresponding
  -    // locations in the type tree.
  -    //
  -    // In other words, List<S> <: List<T> is satisfied provided that
  -    // S <: T.
  -    var S = _newTypeParameter('S');
  -    _checkIsSubtypeMatchOf(list(S), list(T), [T], ['S <: T'], covariant: false);
  -  }
  -
  -  void test_param_on_lhs_contravariant_via_bound() {
  -    // When doing a contravariant match, the type parameters we're trying to
  -    // find types for are on the right hand side.  Is a type parameter also
  -    // appears on the left hand side, we may have to constrain the RHS type
  -    // parameter using the bounds of the LHS type parameter.
  -    //
  -    // In other words, S <: List<T> is satisfied provided that
  -    // bound(S) <: List<T>.
  -    var S = _newTypeParameter('S', list(stringType));
  -    _checkIsSubtypeMatchOf(S, list(T), [T], ['String <: T'], covariant: false);
  -  }
  -
  -  void test_param_on_lhs_covariant() {
  -    // When doing a covariant match, the type parameters we're trying to find
  -    // types for are on the left hand side.
  -    _checkIsSubtypeMatchOf(T, stringType, [T], ['T <: String'],
  -        covariant: true);
  -  }
  -
  -  void test_param_on_rhs_contravariant() {
  -    // When doing a contravariant match, the type parameters we're trying to
  -    // find types for are on the right hand side.
  -    _checkIsSubtypeMatchOf(stringType, T, [T], ['String <: T'],
  -        covariant: false);
  -  }
  -
  -  void test_param_on_rhs_covariant_match() {
  -    // When doing a covariant match, the type parameters we're trying to find
  -    // types for are on the left hand side.  If a type parameter appears on the
  -    // right hand side, there is a condition in which the constraint can be
  -    // satisfied: where both parameters appear at corresponding locations in the
  -    // type tree.
  -    //
  -    // In other words, T <: S can be satisfied trivially by the constraint
  -    // T <: S.
  -    var S = _newTypeParameter('S');
  -    _checkIsSubtypeMatchOf(T, S, [T], ['T <: S'], covariant: true);
  -  }
  -
  -  void test_param_on_rhs_covariant_no_match() {
  -    // When doing a covariant match, the type parameters we're trying to find
  -    // types for are on the left hand side.  If a type parameter appears on the
  -    // right hand side, it's probable that the constraint can't be satisfied,
  -    // because there is no possible type for the LHS (other than bottom)
  -    // that's guaranteed to satisfy the relation for all possible assignments of
  -    // the RHS type parameter.
  -    //
  -    // In other words, no match can be found for List<T> <: S because regardless
  -    // of T, we can't guarantee that List<T> <: S for all S.
  -    var S = _newTypeParameter('S');
  -    _checkIsNotSubtypeMatchOf(list(T), S, [T], covariant: true);
  -  }
  -
  -  void test_related_interface_types_failure() {
  -    _checkIsNotSubtypeMatchOf(iterable(T), list(stringType), [T],
  -        covariant: true);
  -  }
  -
  -  void test_related_interface_types_success() {
  -    _checkIsSubtypeMatchOf(list(T), iterable(stringType), [T], ['T <: String'],
  -        covariant: true);
  -  }
  -
  -  void test_rhs_dynamic() {
  -    // T <: dynamic is trivially satisfied by the constraint T <: dynamic.
  -    _checkIsSubtypeMatchOf(T, dynamicType, [T], ['T <: dynamic'],
  -        covariant: true);
  -    // For any other type X, X <: dynamic is satisfied without the need for any
  -    // constraints.
  -    _checkOrdinarySubtypeMatch(list(T), dynamicType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(stringType, dynamicType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(voidType, dynamicType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(dynamicType, dynamicType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(objectType, dynamicType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(nullType, dynamicType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(fn(intType, stringType), dynamicType, [T],
  -        covariant: true);
  -  }
  -
  -  void test_rhs_object() {
  -    // T <: Object is trivially satisfied by the constraint T <: Object.
  -    _checkIsSubtypeMatchOf(T, objectType, [T], ['T <: Object'],
  -        covariant: true);
  -    // For any other type X, X <: Object is satisfied without the need for any
  -    // constraints.
  -    _checkOrdinarySubtypeMatch(list(T), objectType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(stringType, objectType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(voidType, objectType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(dynamicType, objectType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(objectType, objectType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(nullType, objectType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(fn(intType, stringType), objectType, [T],
  -        covariant: true);
  -  }
  -
  -  void test_rhs_void() {
  -    // T <: void is trivially satisfied by the constraint T <: void.
  -    _checkIsSubtypeMatchOf(T, voidType, [T], ['T <: void'], covariant: true);
  -    // For any other type X, X <: void is satisfied without the need for any
  -    // constraints.
  -    _checkOrdinarySubtypeMatch(list(T), voidType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(stringType, voidType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(voidType, voidType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(dynamicType, voidType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(objectType, voidType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(nullType, voidType, [T], covariant: true);
  -    _checkOrdinarySubtypeMatch(fn(intType, stringType), voidType, [T],
  -        covariant: true);
  -  }
  -
  -  void test_same_interface_types() {
  -    _checkIsSubtypeMatchOf(list(T), list(stringType), [T], ['T <: String'],
  -        covariant: true);
  -  }
  -
  -  void test_x_futureOr_fail_both_branches() {
  -    // List<T> <: FutureOr<String> can't be satisfied because neither
  -    // List<T> <: Future<String> nor List<T> <: int can be satisfied
  -    _checkIsNotSubtypeMatchOf(list(T), futureOr(stringType), [T],
  -        covariant: true);
  -  }
  -
  -  void test_x_futureOr_pass_both_branches_constraints_from_both_branches() {
  -    // Future<String> <: FutureOr<T> can be satisfied because both
  -    // Future<String> <: Future<T> and Future<String> <: T can be satisfied.
  -    // Trying to match Future<String> <: Future<T> generates the constraint
  -    // String <: T, whereas trying to match Future<String> <: T generates the
  -    // constraint Future<String> <: T.  We keep the constraint based on trying
  -    // to match Future<String> <: Future<T>, so String <: T.
  -    _checkIsSubtypeMatchOf(
  -        future(stringType), futureOr(T), [T], ['String <: T'],
  -        covariant: false);
  -  }
  -
  -  void test_x_futureOr_pass_both_branches_constraints_from_future_branch() {
  -    // Future<T> <: FutureOr<Object> can be satisfied because both
  -    // Future<T> <: Future<Object> and Future<T> <: Object can be satisfied.
  -    // Trying to match Future<T> <: Future<Object> generates the constraint
  -    // T <: Object, whereas trying to match Future<T> <: Object generates no
  -    // constraints, so we keep the constraint T <: Object.
  -    _checkIsSubtypeMatchOf(
  -        future(T), futureOr(objectType), [T], ['T <: Object'],
  -        covariant: true);
  -  }
  -
  -  void test_x_futureOr_pass_both_branches_constraints_from_nonFuture_branch() {
  -    // Null <: FutureOr<T> can be satisfied because both
  -    // Null <: Future<T> and Null <: T can be satisfied.
  -    // Trying to match Null <: FutureOr<T> generates no constraints, whereas
  -    // trying to match Null <: T generates the constraint Null <: T,
  -    // so we keep the constraint Null <: T.
  -    _checkIsSubtypeMatchOf(nullType, futureOr(T), [T], ['Null <: T'],
  -        covariant: false);
  -  }
  -
  -  void test_x_futureOr_pass_both_branches_no_constraints() {
  -    // Future<String> <: FutureOr<Object> is satisfied because both
  -    // Future<String> <: Future<Object> and Future<String> <: Object.
  -    // No constraints are recorded.
  -    _checkIsSubtypeMatchOf(future(stringType), futureOr(objectType), [T], [],
  -        covariant: true);
  -  }
  -
  -  void test_x_futureOr_pass_future_branch() {
  -    // Future<T> <: FutureOr<String> can be satisfied because
  -    // Future<T> <: Future<String> can be satisfied
  -    _checkIsSubtypeMatchOf(
  -        future(T), futureOr(stringType), [T], ['T <: String'],
  -        covariant: true);
  -  }
  -
  -  void test_x_futureOr_pass_nonFuture_branch() {
  -    // List<T> <: FutureOr<List<String>> can be satisfied because
  -    // List<T> <: List<String> can be satisfied
  -    _checkIsSubtypeMatchOf(
  -        list(T), futureOr(list(stringType)), [T], ['T <: String'],
  -        covariant: true);
  -  }
  -
  -  void _checkIsNotSubtypeMatchOf(
  -      DartType t1, DartType t2, Iterable<TypeParameterType> typeFormals,
  -      {bool covariant}) {
  -    var inferrer = new GenericInferrer(
  -        typeProvider, typeSystem, typeFormals.map((t) => t.element));
  -    var success =
  -        inferrer.tryMatchSubtypeOf(t1, t2, null, covariant: covariant);
  -    expect(success, isFalse);
  -    inferrer.constraints.forEach((typeParameter, constraintsForTypeParameter) {
  -      expect(constraintsForTypeParameter, isEmpty);
  -    });
  -  }
  -
  -  void _checkIsSubtypeMatchOf(
  -      DartType t1,
  -      DartType t2,
  -      Iterable<TypeParameterType> typeFormals,
  -      Iterable<String> expectedConstraints,
  -      {bool covariant}) {
  -    var inferrer = new GenericInferrer(
  -        typeProvider, typeSystem, typeFormals.map((t) => t.element));
  -    var success =
  -        inferrer.tryMatchSubtypeOf(t1, t2, null, covariant: covariant);
  -    expect(success, isTrue);
  -    var formattedConstraints = <String>[];
  -    inferrer.constraints.forEach((typeParameter, constraintsForTypeParameter) {
  -      for (var constraint in constraintsForTypeParameter) {
  -        formattedConstraints.add(constraint.format(typeParameter.toString()));
  -      }
  -    });
  -    expect(formattedConstraints, unorderedEquals(expectedConstraints));
  -  }
  -
  -  void _checkOrdinarySubtypeMatch(
  -      DartType t1, DartType t2, Iterable<TypeParameterType> typeFormals,
  -      {bool covariant}) {
  -    bool expectSuccess = typeSystem.isSubtypeOf(t1, t2);
  -    if (expectSuccess) {
  -      _checkIsSubtypeMatchOf(t1, t2, typeFormals, [], covariant: covariant);
  -    } else {
  -      _checkIsNotSubtypeMatchOf(t1, t2, typeFormals);
  -    }
  -  }
  -
  -  TypeParameterType _newTypeParameter(String name, [DartType bound]) {
  -    var element = new TypeParameterElementImpl(name, 0);
  -    if (bound != null) {
  -      element.bound = bound;
  -    }
  -    return new TypeParameterTypeImpl(element);
  -  }
  -}
  -
  -/**
  - * Base class for testing LUB in spec and strong mode.
  - * Defines helper functions and tests. Tests here are ones whose behavior is
  - * the same in strong and spec mode.
  - */
  -abstract class LeastUpperBoundTestBase extends BoundTestBase {
  -  void test_bottom_function() {
  -    _checkLeastUpperBound(bottomType, simpleFunctionType, simpleFunctionType);
  -  }
  -
  -  void test_bottom_interface() {
  -    DartType interfaceType = ElementFactory.classElement2('A', []).type;
  -    _checkLeastUpperBound(bottomType, interfaceType, interfaceType);
  -  }
  -
  -  void test_bottom_typeParam() {
  -    DartType typeParam = ElementFactory.typeParameterElement('T').type;
  -    _checkLeastUpperBound(bottomType, typeParam, typeParam);
  -  }
  -
  -  void test_directInterfaceCase() {
  -    // class A
  -    // class B implements A
  -    // class C implements B
  -    ClassElementImpl classA = ElementFactory.classElement2("A");
  -    ClassElementImpl classB = ElementFactory.classElement2("B");
  -    ClassElementImpl classC = ElementFactory.classElement2("C");
  -    InterfaceType typeA = classA.type;
  -    InterfaceType typeB = classB.type;
  -    InterfaceType typeC = classC.type;
  -    classB.interfaces = <InterfaceType>[typeA];
  -    classC.interfaces = <InterfaceType>[typeB];
  -    _checkLeastUpperBound(typeB, typeC, typeB);
  -  }
  -
  -  void test_directSubclassCase() {
  -    // class A
  -    // class B extends A
  -    // class C extends B
  -    ClassElementImpl classA = ElementFactory.classElement2("A");
  -    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
  -    ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
  -    InterfaceType typeB = classB.type;
  -    InterfaceType typeC = classC.type;
  -    _checkLeastUpperBound(typeB, typeC, typeB);
  -  }
  -
  -  void test_dynamic_bottom() {
  -    _checkLeastUpperBound(dynamicType, bottomType, dynamicType);
  -  }
  -
  -  void test_dynamic_function() {
  -    _checkLeastUpperBound(dynamicType, simpleFunctionType, dynamicType);
  -  }
  -
  -  void test_dynamic_interface() {
  -    DartType interfaceType = ElementFactory.classElement2('A', []).type;
  -    _checkLeastUpperBound(dynamicType, interfaceType, dynamicType);
  -  }
  -
  -  void test_dynamic_typeParam() {
  -    DartType typeParam = ElementFactory.typeParameterElement('T').type;
  -    _checkLeastUpperBound(dynamicType, typeParam, dynamicType);
  -  }
  -
  -  void test_dynamic_void() {
  -    // Note: _checkLeastUpperBound tests `LUB(x, y)` as well as `LUB(y, x)`
  -    _checkLeastUpperBound(dynamicType, voidType, voidType);
  -  }
  -
  -  void test_functionsDifferentRequiredArity() {
  -    FunctionType type1 = _functionType([intType, intType]);
  -    FunctionType type2 = _functionType([intType, intType, intType]);
  -    _checkLeastUpperBound(type1, type2, functionType);
  -  }
  -
  -  void test_functionsIgnoreExtraNamedParams() {
  -    FunctionType type1 = _functionType([], named: {'a': intType, 'b': intType});
  -    FunctionType type2 = _functionType([], named: {'a': intType, 'c': intType});
  -    FunctionType expected = _functionType([], named: {'a': intType});
  -    _checkLeastUpperBound(type1, type2, expected);
  -  }
  -
  -  void test_functionsIgnoreExtraPositionalParams() {
  -    FunctionType type1 =
  -        _functionType([], optional: [intType, intType, stringType]);
  -    FunctionType type2 = _functionType([], optional: [intType]);
  -    FunctionType expected = _functionType([], optional: [intType]);
  -    _checkLeastUpperBound(type1, type2, expected);
  -  }
  -
  -  void test_functionsLubReturnType() {
  -    FunctionType type1 = _functionType([], returns: intType);
  -    FunctionType type2 = _functionType([], returns: doubleType);
  -    FunctionType expected = _functionType([], returns: numType);
  -    _checkLeastUpperBound(type1, type2, expected);
  -  }
  -
  -  void test_functionsSameType() {
  -    FunctionType type1 = _functionType([stringType, intType, numType],
  -        optional: [doubleType], named: {'n': numType}, returns: intType);
  -    FunctionType type2 = _functionType([stringType, intType, numType],
  -        optional: [doubleType], named: {'n': numType}, returns: intType);
  -    FunctionType expected = _functionType([stringType, intType, numType],
  -        optional: [doubleType], named: {'n': numType}, returns: intType);
  -    _checkLeastUpperBound(type1, type2, expected);
  -  }
  -
  -  void test_interface_function() {
  -    DartType interfaceType = ElementFactory.classElement2('A', []).type;
  -    _checkLeastUpperBound(interfaceType, simpleFunctionType, objectType);
  -  }
  -
  -  void test_mixinCase() {
  -    // class A
  -    // class B extends A
  -    // class C extends A
  -    // class D extends B with M, N, O, P
  -    ClassElement classA = ElementFactory.classElement2("A");
  -    ClassElement classB = ElementFactory.classElement("B", classA.type);
  -    ClassElement classC = ElementFactory.classElement("C", classA.type);
  -    ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
  -    InterfaceType typeA = classA.type;
  -    InterfaceType typeC = classC.type;
  -    InterfaceType typeD = classD.type;
  -    classD.mixins = <InterfaceType>[
  -      ElementFactory.classElement2("M").type,
  -      ElementFactory.classElement2("N").type,
  -      ElementFactory.classElement2("O").type,
  -      ElementFactory.classElement2("P").type
  -    ];
  -    _checkLeastUpperBound(typeD, typeC, typeA);
  -  }
  -
  -  void test_nestedFunctionsLubInnerParamTypes() {
  -    FunctionType type1 = _functionType([
  -      _functionType([stringType, intType, intType])
  -    ]);
  -    FunctionType type2 = _functionType([
  -      _functionType([intType, doubleType, numType])
  -    ]);
  -    FunctionType expected = _functionType([
  -      _functionType([objectType, numType, numType])
  -    ]);
  -    _checkLeastUpperBound(type1, type2, expected);
  -  }
  -
  -  void test_object() {
  -    ClassElementImpl classA = ElementFactory.classElement2("A");
  -    ClassElementImpl classB = ElementFactory.classElement2("B");
  -    InterfaceType typeA = classA.type;
  -    InterfaceType typeB = classB.type;
  -    DartType typeObject = typeA.element.supertype;
  -    // assert that object does not have a super type
  -    expect((typeObject.element as ClassElement).supertype, isNull);
  -    // assert that both A and B have the same super type of Object
  -    expect(typeB.element.supertype, typeObject);
  -    // finally, assert that the only least upper bound of A and B is Object
  -    _checkLeastUpperBound(typeA, typeB, typeObject);
  -  }
  -
  -  void test_self() {
  -    DartType typeParam = ElementFactory.typeParameterElement('T').type;
  -    DartType interfaceType = ElementFactory.classElement2('A', []).type;
  -
  -    List<DartType> types = [
  -      dynamicType,
  -      voidType,
  -      bottomType,
  -      typeParam,
  -      interfaceType,
  -      simpleFunctionType
  -    ];
  -
  -    for (DartType type in types) {
  -      _checkLeastUpperBound(type, type, type);
  -    }
  -  }
  -
  -  void test_sharedSuperclass1() {
  -    ClassElementImpl classA = ElementFactory.classElement2("A");
  -    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
  -    ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
  -    InterfaceType typeA = classA.type;
  -    InterfaceType typeB = classB.type;
  -    InterfaceType typeC = classC.type;
  -    _checkLeastUpperBound(typeB, typeC, typeA);
  -  }
  -
  -  void test_sharedSuperclass2() {
  -    ClassElementImpl classA = ElementFactory.classElement2("A");
  -    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
  -    ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
  -    ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
  -    InterfaceType typeA = classA.type;
  -    InterfaceType typeB = classB.type;
  -    InterfaceType typeD = classD.type;
  -    _checkLeastUpperBound(typeB, typeD, typeA);
  -  }
  -
  -  void test_sharedSuperclass3() {
  -    ClassElementImpl classA = ElementFactory.classElement2("A");
  -    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
  -    ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
  -    ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
  -    InterfaceType typeB = classB.type;
  -    InterfaceType typeC = classC.type;
  -    InterfaceType typeD = classD.type;
  -    _checkLeastUpperBound(typeC, typeD, typeB);
  -  }
  -
  -  void test_sharedSuperclass4() {
  -    ClassElement classA = ElementFactory.classElement2("A");
  -    ClassElement classA2 = ElementFactory.classElement2("A2");
  -    ClassElement classA3 = ElementFactory.classElement2("A3");
  -    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
  -    ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
  -    InterfaceType typeA = classA.type;
  -    InterfaceType typeA2 = classA2.type;
  -    InterfaceType typeA3 = classA3.type;
  -    InterfaceType typeB = classB.type;
  -    InterfaceType typeC = classC.type;
  -    classB.interfaces = <InterfaceType>[typeA2];
  -    classC.interfaces = <InterfaceType>[typeA3];
  -    _checkLeastUpperBound(typeB, typeC, typeA);
  -  }
  -
  -  void test_sharedSuperinterface1() {
  -    ClassElementImpl classA = ElementFactory.classElement2("A");
  -    ClassElementImpl classB = ElementFactory.classElement2("B");
  -    ClassElementImpl classC = ElementFactory.classElement2("C");
  -    InterfaceType typeA = classA.type;
  -    InterfaceType typeB = classB.type;
  -    InterfaceType typeC = classC.type;
  -    classB.interfaces = <InterfaceType>[typeA];
  -    classC.interfaces = <InterfaceType>[typeA];
  -    _checkLeastUpperBound(typeB, typeC, typeA);
  -  }
  -
  -  void test_sharedSuperinterface2() {
  -    ClassElementImpl classA = ElementFactory.classElement2("A");
  -    ClassElementImpl classB = ElementFactory.classElement2("B");
  -    ClassElementImpl classC = ElementFactory.classElement2("C");
  -    ClassElementImpl classD = ElementFactory.classElement2("D");
  -    InterfaceType typeA = classA.type;
  -    InterfaceType typeB = classB.type;
  -    InterfaceType typeC = classC.type;
  -    InterfaceType typeD = classD.type;
  -    classB.interfaces = <InterfaceType>[typeA];
  -    classC.interfaces = <InterfaceType>[typeA];
  -    classD.interfaces = <InterfaceType>[typeC];
  -    _checkLeastUpperBound(typeB, typeD, typeA);
  -  }
  -
  -  void test_sharedSuperinterface3() {
  -    ClassElementImpl classA = ElementFactory.classElement2("A");
  -    ClassElementImpl classB = ElementFactory.classElement2("B");
  -    ClassElementImpl classC = ElementFactory.classElement2("C");
  -    ClassElementImpl classD = ElementFactory.classElement2("D");
  -    InterfaceType typeA = classA.type;
  -    InterfaceType typeB = classB.type;
  -    InterfaceType typeC = classC.type;
  -    InterfaceType typeD = classD.type;
  -    classB.interfaces = <InterfaceType>[typeA];
  -    classC.interfaces = <InterfaceType>[typeB];
  -    classD.interfaces = <InterfaceType>[typeB];
  -    _checkLeastUpperBound(typeC, typeD, typeB);
  -  }
  -
  -  void test_sharedSuperinterface4() {
  -    ClassElement classA = ElementFactory.classElement2("A");
  -    ClassElement classA2 = ElementFactory.classElement2("A2");
  -    ClassElement classA3 = ElementFactory.classElement2("A3");
  -    ClassElementImpl classB = ElementFactory.classElement2("B");
  -    ClassElementImpl classC = ElementFactory.classElement2("C");
  -    InterfaceType typeA = classA.type;
  -    InterfaceType typeA2 = classA2.type;
  -    InterfaceType typeA3 = classA3.type;
  -    InterfaceType typeB = classB.type;
  -    InterfaceType typeC = classC.type;
  -    classB.interfaces = <InterfaceType>[typeA, typeA2];
  -    classC.interfaces = <InterfaceType>[typeA, typeA3];
  -    _checkLeastUpperBound(typeB, typeC, typeA);
  -  }
  -
  -  void test_twoComparables() {
  -    _checkLeastUpperBound(stringType, numType, objectType);
  -  }
  -
  -  void test_typeParam_function_bounded() {
  -    TypeParameterElementImpl typeParamElement =
  -        ElementFactory.typeParameterElement('T');
  -    typeParamElement.bound = functionType;
  -    DartType typeParam = typeParamElement.type;
  -    _checkLeastUpperBound(typeParam, simpleFunctionType, functionType);
  -  }
  -
  -  void test_typeParam_function_noBound() {
  -    DartType typeParam = ElementFactory.typeParameterElement('T').type;
  -    _checkLeastUpperBound(typeParam, simpleFunctionType, objectType);
  -  }
  -
  -  void test_typeParam_interface_bounded() {
  -    DartType typeA = ElementFactory.classElement2('A', []).type;
  -    DartType typeB = ElementFactory.classElement('B', typeA).type;
  -    DartType typeC = ElementFactory.classElement('C', typeA).type;
  -    TypeParameterElementImpl typeParamElement =
  -        ElementFactory.typeParameterElement('T');
  -    typeParamElement.bound = typeB;
  -    DartType typeParam = typeParamElement.type;
  -    _checkLeastUpperBound(typeParam, typeC, typeA);
  -  }
  -
  -  void test_typeParam_interface_noBound() {
  -    DartType typeParam = ElementFactory.typeParameterElement('T').type;
  -    DartType interfaceType = ElementFactory.classElement2('A', []).type;
  -    _checkLeastUpperBound(typeParam, interfaceType, objectType);
  -  }
  -
  -  void test_typeParameters_same() {
  -    // List<int>
  -    // List<int>
  -    InterfaceType listOfIntType = listType.instantiate(<DartType>[intType]);
  -    _checkLeastUpperBound(listOfIntType, listOfIntType, listOfIntType);
  -  }
  -
  -  void test_void() {
  -    List<DartType> types = [
  -      bottomType,
  -      simpleFunctionType,
  -      ElementFactory.classElement2('A', []).type,
  -      ElementFactory.typeParameterElement('T').type
  -    ];
  -    for (DartType type in types) {
  -      _checkLeastUpperBound(
  -          _functionType([], returns: voidType),
  -          _functionType([], returns: type),
  -          _functionType([], returns: voidType));
  -    }
  -  }
  -}
  -
  -@reflectiveTest
  -class NonNullableSubtypingTest extends StrongSubtypingTestBase {
  -  @override
  -  void setUp() {
  -    typeProvider = AnalysisContextFactory.contextWithCoreAndOptions(
  -            new AnalysisOptionsImpl()
  -              ..contextFeatures = FeatureSet.forTesting(
  -                  additionalFeatures: [Feature.non_nullable]),
  -            resourceProvider: new MemoryResourceProvider())
  -        .typeProvider;
  -
  -    // TypeSystem should use the context type provider.
  -    typeSystem = new Dart2TypeSystem(typeProvider);
  -
  -    LibraryElement coreLibrary = typeProvider.objectType.element.library;
  -    LibraryElement asyncLibrary = typeProvider.streamType.element.library;
  -
  -    // Get a non-nullable type provider for convience during the test.
  -    typeProvider = new NonNullableTypeProvider(coreLibrary, asyncLibrary);
  -  }
  -
  -  void test_int_nullableTypes() {
  -    List<DartType> equivalents = <DartType>[
  -      intType,
  -      _star(intType),
  -    ];
  -    List<DartType> supertypes = <DartType>[
  -      _question(intType),
  -      objectType,
  -      _question(objectType),
  -    ];
  -    List<DartType> unrelated = <DartType>[doubleType, nullType];
  -    _checkGroups(intType,
  -        equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
  -  }
  -
  -  void test_intQuestion_nullableTypes() {
  -    List<DartType> equivalents = <DartType>[
  -      _question(intType),
  -      _star(intType),
  -    ];
  -    List<DartType> subtypes = <DartType>[
  -      intType,
  -      nullType,
  -    ];
  -    List<DartType> supertypes = <DartType>[
  -      _question(numType),
  -      _star(numType),
  -      _question(objectType),
  -      _star(objectType),
  -    ];
  -    List<DartType> unrelated = <DartType>[doubleType, numType, objectType];
  -    _checkGroups(_question(intType),
  -        equivalents: equivalents,
  -        supertypes: supertypes,
  -        unrelated: unrelated,
  -        subtypes: subtypes);
  -  }
  -
  -  void test_intStar_nullableTypes() {
  -    List<DartType> equivalents = <DartType>[
  -      intType,
  -      _question(intType),
  -      _star(intType),
  -    ];
  -    List<DartType> subtypes = <DartType>[nullType];
  -    List<DartType> supertypes = <DartType>[
  -      numType,
  -      _question(numType),
  -      _star(numType),
  -      objectType,
  -      _question(objectType),
  -    ];
  -    List<DartType> unrelated = <DartType>[doubleType];
  -    _checkGroups(_star(intType),
  -        equivalents: equivalents,
  -        supertypes: supertypes,
  -        unrelated: unrelated,
  -        subtypes: subtypes);
  -  }
  -
  -  DartType _question(DartType dartType) =>
  -      (dartType as TypeImpl).withNullability(NullabilitySuffix.question);
  -
  -  DartType _star(DartType dartType) =>
  -      (dartType as TypeImpl).withNullability(NullabilitySuffix.star);
  -}
  -
  -@reflectiveTest
  -class StrongAssignabilityTest extends AbstractTypeSystemTest {
  +class AssignabilityTest extends AbstractTypeSystemTest {
     void test_isAssignableTo_bottom_isBottom() {
       DartType interfaceType = ElementFactory.classElement2('A', []).type;
       List<DartType> interassignable = <DartType>[
  
positive.code:   }
  }
  
  /**
   * Tests GLB, which only exists in strong mode.
   */
  @reflectiveTest
  class StrongGreatestLowerBoundTest extends BoundTestBase {
    void setUp() {
      super.setUp();
      typeSystem = new Dart2TypeSystem(typeProvider);
  
negative.code:     _checkLeastUpperBound(s, u, AType.instantiate([objectType]));
    }
  
    void test_typeParam_function_bounded() {
      TypeParameterElementImpl typeParamElement =
          ElementFactory.typeParameterElement('T');
      typeParamElement.bound = functionType;
      DartType typeParam = typeParamElement.type;
      _checkLeastUpperBound(typeParam, simpleFunctionType, functionType);
    }
  
    void test_typeParam_function_noBound() {
      DartType typeParam = ElementFactory.typeParameterElement('T').type;
      _checkLeastUpperBound(typeParam, simpleFunctionType, objectType);
    }
  
    void test_typeParam_interface_bounded() {
      DartType typeA = ElementFactory.classElement2('A', []).type;
      DartType typeB = ElementFactory.classElement('B', typeA).type;
      DartType typeC = ElementFactory.classElement('C', typeA).type;
      TypeParameterElementImpl typeParamElement =
          ElementFactory.typeParameterElement('T');
      typeParamElement.bound = typeB;
      DartType typeParam = typeParamElement.type;
      _checkLeastUpperBound(typeParam, typeC, typeA);
    }
  
    void test_typeParam_interface_noBound() {
      DartType typeParam = ElementFactory.typeParameterElement('T').type;
      DartType interfaceType = ElementFactory.classElement2('A', []).type;
      _checkLeastUpperBound(typeParam, interfaceType, objectType);
    }
  
    /// Check least upper bound of the same class with different type parameters.
    void test_typeParameters_different() {
      // class List<int>
  