diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index a369c9c..1f4fe07 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -85,7 +85,7 @@
 /// TODO(scheglov) Clean up the list of implicitly analyzed files.
 class AnalysisDriver implements AnalysisDriverGeneric {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 110;
+  static const int DATA_VERSION = 111;
 
   /// The length of the list returned by [_computeDeclaredVariablesSignature].
   static const int _declaredVariablesSignatureLength = 4;
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index db34b39..0a3dee5 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -115,7 +115,7 @@
   final FeatureSet _contextFeatureSet;
 
   /// The language version for the package that contains this file.
-  final Version _packageLanguageVersion;
+  final Version packageLanguageVersion;
 
   int id = fileObjectId++;
   int refreshId;
@@ -156,7 +156,7 @@
     this.source,
     this.workspacePackage,
     this._contextFeatureSet,
-    this._packageLanguageVersion,
+    this.packageLanguageVersion,
   ) : isInExternalSummaries = false;
 
   FileState._external(this._fsState, this.uri)
@@ -166,7 +166,7 @@
         workspacePackage = null,
         _exists = true,
         _contextFeatureSet = null,
-        _packageLanguageVersion = null {
+        packageLanguageVersion = null {
     _apiSignature = Uint8List(16);
     _libraryCycle = LibraryCycle.external();
   }
@@ -375,7 +375,7 @@
       var signature = ApiSignature();
       signature.addUint32List(_fsState._saltForUnlinked);
       signature.addFeatureSet(_contextFeatureSet);
-      signature.addLanguageVersion(_packageLanguageVersion);
+      signature.addLanguageVersion(packageLanguageVersion);
       signature.addString(_contentHash);
       signature.addBool(_exists);
       contentSignature = signature.toByteList();
@@ -510,7 +510,7 @@
     unit.lineInfo = LineInfo(const <int>[0]);
 
     unit.languageVersion = LibraryLanguageVersion(
-      package: _packageLanguageVersion,
+      package: packageLanguageVersion,
       override: null,
     );
 
@@ -561,7 +561,7 @@
       ..configureFeatures(
         featureSetForOverriding: _contextFeatureSet,
         featureSet: _contextFeatureSet.restrictToVersion(
-          _packageLanguageVersion,
+          packageLanguageVersion,
         ),
       );
     Token token = scanner.tokenize(reportScannerErrors: false);
@@ -640,7 +640,7 @@
 
     var unitImpl = unit as CompilationUnitImpl;
     unitImpl.languageVersion = LibraryLanguageVersion(
-      package: _packageLanguageVersion,
+      package: packageLanguageVersion,
       override: overrideVersion,
     );
   }
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
index 95e4972..dfcfb0d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
@@ -125,6 +125,7 @@
     for (var node in scc) {
       cycle.libraries.add(node.file);
 
+      signature.addLanguageVersion(node.file.packageLanguageVersion);
       signature.addString(node.file.uriStr);
 
       signature.addInt(node.file.libraryFiles.length);
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index f27c23b..e4c683a 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -11,7 +11,7 @@
 import 'package:analyzer/dart/element/nullability_suffix.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
-import 'package:analyzer/dart/element/type_system.dart' as public;
+import 'package:analyzer/dart/element/type_system.dart';
 import 'package:analyzer/error/listener.dart' show ErrorReporter;
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/generic_inferrer.dart';
@@ -30,395 +30,15 @@
 import 'package:analyzer/src/dart/element/type_schema_elimination.dart';
 import 'package:meta/meta.dart';
 
-/// The interface `TypeSystem` defines the behavior of an object representing
-/// the type system.  This provides a common location to put methods that act on
-/// types but may need access to more global data structures, and it paves the
-/// way for a possible future where we may wish to make the type system
-/// pluggable.
-// TODO(brianwilkerson) Rename this class to TypeSystemImpl.
-abstract class TypeSystem2 implements public.TypeSystem {
+/// The [TypeSystem] implementation.
+class TypeSystemImpl implements TypeSystem {
   /// If `true`, then NNBD type rules should be used.
   /// If `false`, then legacy type rules should be used.
   final bool isNonNullableByDefault;
 
-  TypeSystem2({@required this.isNonNullableByDefault});
+  /// The provider of types for the system.
+  final TypeProviderImpl typeProvider;
 
-  /// The provider of types for the system
-  TypeProvider get typeProvider;
-
-  @override
-  TypeImpl flatten(DartType type) {
-    if (identical(type, UnknownInferredType.instance)) {
-      return type;
-    }
-
-    // if T is S? then flatten(T) = flatten(S)?
-    // if T is S* then flatten(T) = flatten(S)*
-    NullabilitySuffix nullabilitySuffix = type.nullabilitySuffix;
-    if (nullabilitySuffix != NullabilitySuffix.none) {
-      var S = (type as TypeImpl).withNullability(NullabilitySuffix.none);
-      return flatten(S).withNullability(nullabilitySuffix);
-    }
-
-    if (type is InterfaceType) {
-      // Implement the cases:
-      //  - "If T = FutureOr<S> then flatten(T) = S."
-      //  - "If T = Future<S> then flatten(T) = S."
-      if (type.isDartAsyncFutureOr || type.isDartAsyncFuture) {
-        return type.typeArguments.isNotEmpty
-            ? type.typeArguments[0]
-            : DynamicTypeImpl.instance;
-      }
-      // Implement the case: "Otherwise if T <: Future then let S be a type
-      // such that T << Future<S> and for all R, if T << Future<R> then S << R.
-      // Then flatten(T) = S."
-      //
-      // In other words, given the set of all types R such that T << Future<R>,
-      // let S be the most specific of those types, if any such S exists.
-      //
-      // Since we only care about the most specific type, it is sufficient to
-      // look at the types appearing as a parameter to Future in the type
-      // hierarchy of T.  We don't need to consider the supertypes of those
-      // types, since they are by definition less specific.
-      List<DartType> candidateTypes =
-          _searchTypeHierarchyForFutureTypeParameters(type);
-      DartType flattenResult =
-          InterfaceTypeImpl.findMostSpecificType(candidateTypes, this);
-      if (flattenResult != null) {
-        return flattenResult;
-      }
-    }
-    // Implement the case: "In any other circumstance, flatten(T) = T."
-    return type;
-  }
-
-  DartType futureOrBase(DartType type) {
-    // If `T` is `FutureOr<S>` for some `S`,
-    // then `futureOrBase(T)` = `futureOrBase(S)`
-    if (type is InterfaceType && type.isDartAsyncFutureOr) {
-      return futureOrBase(
-        type.typeArguments[0],
-      );
-    }
-
-    // Otherwise `futureOrBase(T)` = `T`.
-    return type;
-  }
-
-  List<InterfaceType> gatherMixinSupertypeConstraintsForInference(
-      ClassElement mixinElement) {
-    List<InterfaceType> candidates;
-    if (mixinElement.isMixin) {
-      candidates = mixinElement.superclassConstraints;
-    } else {
-      candidates = [mixinElement.supertype];
-      candidates.addAll(mixinElement.mixins);
-      if (mixinElement.isMixinApplication) {
-        candidates.removeLast();
-      }
-    }
-    return candidates
-        .where((type) => type.element.typeParameters.isNotEmpty)
-        .toList();
-  }
-
-  /// Compute the least upper bound of two types.
-  DartType getLeastUpperBound(DartType type1, DartType type2);
-
-  /// Given a [DartType] [type], instantiate it with its bounds.
-  ///
-  /// The behavior of this method depends on the type system, for example, in
-  /// classic Dart `dynamic` will be used for all type arguments, whereas
-  /// strong mode prefers the actual bound type if it was specified.
-  DartType instantiateToBounds(DartType type, {List<bool> hasError});
-
-  /// Given a [DartType] [type] and a list of types
-  /// [typeArguments], instantiate the type formals with the
-  /// provided actuals.  If [type] is not a parameterized type,
-  /// no instantiation is done.
-  DartType instantiateType(DartType type, List<DartType> typeArguments) {
-    if (type is FunctionType) {
-      return type.instantiate(typeArguments);
-    } else if (type is InterfaceTypeImpl) {
-      // TODO(scheglov) Use `ClassElement.instantiate()`, don't use raw types.
-      return type.element.instantiate(
-        typeArguments: typeArguments,
-        nullabilitySuffix: type.nullabilitySuffix,
-      );
-    } else {
-      return type;
-    }
-  }
-
-  /// Given uninstantiated [typeFormals], instantiate them to their bounds.
-  List<DartType> instantiateTypeFormalsToBounds(
-      List<TypeParameterElement> typeFormals,
-      {List<bool> hasError});
-
-  /// Return `true` if the [leftType] is assignable to the [rightType] (that is,
-  /// if leftType <==> rightType).
-  @override
-  bool isAssignableTo(DartType leftType, DartType rightType);
-
-  /// Return `true` if the [leftType] is more specific than the [rightType]
-  /// (that is, if leftType << rightType), as defined in the Dart language spec.
-  ///
-  /// In strong mode, this is equivalent to [isSubtypeOf].
-  @Deprecated('Use isSubtypeOf() instead.')
-  bool isMoreSpecificThan(DartType leftType, DartType rightType);
-
-  @override
-  bool isNonNullable(DartType type) {
-    if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
-      return false;
-    } else if (type is TypeParameterTypeImpl && type.promotedBound != null) {
-      return isNonNullable(type.promotedBound);
-    } else if (type.nullabilitySuffix == NullabilitySuffix.question) {
-      return false;
-    } else if (type is InterfaceType && type.isDartAsyncFutureOr) {
-      return isNonNullable(type.typeArguments[0]);
-    } else if (type is TypeParameterType) {
-      var bound = type.element.bound;
-      return bound != null && isNonNullable(bound);
-    }
-    return true;
-  }
-
-  @override
-  bool isNullable(DartType type) {
-    if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
-      return true;
-    } else if (type is TypeParameterTypeImpl && type.promotedBound != null) {
-      return isNullable(type.promotedBound);
-    } else if (type.nullabilitySuffix == NullabilitySuffix.question) {
-      return true;
-    } else if (type.isDartAsyncFutureOr) {
-      return isNullable((type as InterfaceType).typeArguments[0]);
-    }
-    return false;
-  }
-
-  @override
-  bool isPotentiallyNonNullable(DartType type) => !isNullable(type);
-
-  @override
-  bool isPotentiallyNullable(DartType type) => !isNonNullable(type);
-
-  @override
-  bool isStrictlyNonNullable(DartType type) {
-    if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
-      return false;
-    } else if (type.nullabilitySuffix != NullabilitySuffix.none) {
-      return false;
-    } else if (type is InterfaceType && type.isDartAsyncFutureOr) {
-      return isStrictlyNonNullable(type.typeArguments[0]);
-    } else if (type is TypeParameterType) {
-      return isStrictlyNonNullable(type.bound);
-    }
-    return true;
-  }
-
-  /// Return `true` if the [leftType] is a subtype of the [rightType] (that is,
-  /// if leftType <: rightType).
-  @override
-  bool isSubtypeOf(DartType leftType, DartType rightType);
-
-  @override
-  DartType leastUpperBound(DartType leftType, DartType rightType) {
-    if (!NullSafetyUnderstandingFlag.isEnabled) {
-      leftType = NullabilityEliminator.perform(typeProvider, leftType);
-      rightType = NullabilityEliminator.perform(typeProvider, rightType);
-    }
-    return getLeastUpperBound(leftType, rightType);
-  }
-
-  /// Returns a nullable version of [type].  The result would be equivalent to
-  /// the union `type | Null` (if we supported union types).
-  DartType makeNullable(TypeImpl type) {
-    // TODO(paulberry): handle type parameter types
-    return type.withNullability(NullabilitySuffix.question);
-  }
-
-  /// Attempts to find the appropriate substitution for the [mixinElement]
-  /// type parameters that can be applied to [srcTypes] to make it equal to
-  /// [destTypes].  If no such substitution can be found, `null` is returned.
-  List<DartType> matchSupertypeConstraints(
-    ClassElement mixinElement,
-    List<DartType> srcTypes,
-    List<DartType> destTypes,
-  ) {
-    var typeParameters = mixinElement.typeParameters;
-    var inferrer = GenericInferrer(this, typeParameters);
-    for (int i = 0; i < srcTypes.length; i++) {
-      inferrer.constrainReturnType(srcTypes[i], destTypes[i]);
-      inferrer.constrainReturnType(destTypes[i], srcTypes[i]);
-    }
-
-    var inferredTypes = inferrer.infer(
-      typeParameters,
-      considerExtendsClause: false,
-    );
-    var substitution = Substitution.fromPairs(typeParameters, inferredTypes);
-
-    for (int i = 0; i < srcTypes.length; i++) {
-      var srcType = substitution.substituteType(srcTypes[i]);
-      var destType = destTypes[i];
-      if (isNonNullableByDefault) {
-        // TODO(scheglov) waiting for the spec
-        // https://github.com/dart-lang/sdk/issues/42605
-      } else {
-        srcType = toLegacyType(srcType);
-        destType = toLegacyType(destType);
-      }
-      if (srcType != destType) {
-        // Failed to find an appropriate substitution
-        return null;
-      }
-    }
-
-    return inferredTypes;
-  }
-
-  /// Returns a non-nullable version of [type].  This is equivalent to the
-  /// operation `NonNull` defined in the spec.
-  @override
-  DartType promoteToNonNull(DartType type) {
-    if (type.isDartCoreNull) return NeverTypeImpl.instance;
-
-    if (type is TypeParameterTypeImpl) {
-      var element = type.element;
-
-      // NonNull(X & T) = X & NonNull(T)
-      if (type.promotedBound != null) {
-        var promotedBound = promoteToNonNull(type.promotedBound);
-        return TypeParameterTypeImpl(
-          element: element,
-          nullabilitySuffix: NullabilitySuffix.none,
-          promotedBound: promotedBound,
-        );
-      }
-
-      // NonNull(X) = X & NonNull(B), where B is the bound of X
-      var promotedBound = element.bound != null
-          ? promoteToNonNull(element.bound)
-          : typeProvider.objectType;
-      if (identical(promotedBound, element.bound)) {
-        promotedBound = null;
-      }
-      return TypeParameterTypeImpl(
-        element: element,
-        nullabilitySuffix: NullabilitySuffix.none,
-        promotedBound: promotedBound,
-      );
-    }
-
-    return (type as TypeImpl).withNullability(NullabilitySuffix.none);
-  }
-
-  /// Determine the type of a binary expression with the given [operator] whose
-  /// left operand has the type [leftType] and whose right operand has the type
-  /// [rightType], given that resolution has so far produced the [currentType].
-  DartType refineBinaryExpressionType(DartType leftType, TokenType operator,
-      DartType rightType, DartType currentType, MethodElement operatorElement);
-
-  /// Determines the context type for the parameters of a method invocation
-  /// where the type of the target is [targetType], the method being invoked is
-  /// [methodElement], the context surrounding the method invocation is
-  /// [invocationContext], and the context type produced so far by resolution is
-  /// [currentType].
-  DartType refineNumericInvocationContext(DartType targetType,
-      Element methodElement, DartType invocationContext, DartType currentType);
-
-  /// Determines the type of a method invocation where the type of the target is
-  /// [targetType], the method being invoked is [methodElement], the types of
-  /// the arguments passed to the method are [argumentTypes], and the type
-  /// produced so far by resolution is [currentType].
-  DartType refineNumericInvocationType(
-      DartType targetType,
-      MethodElement methodElement,
-      List<DartType> argumentTypes,
-      DartType currentType);
-
-  @override
-  DartType resolveToBound(DartType type) {
-    if (type is TypeParameterTypeImpl) {
-      var element = type.element;
-
-      var bound = element.bound;
-      if (bound == null) {
-        return typeProvider.objectType;
-      }
-
-      NullabilitySuffix nullabilitySuffix = type.nullabilitySuffix;
-      NullabilitySuffix newNullabilitySuffix;
-      if (nullabilitySuffix == NullabilitySuffix.question ||
-          bound.nullabilitySuffix == NullabilitySuffix.question) {
-        newNullabilitySuffix = NullabilitySuffix.question;
-      } else if (nullabilitySuffix == NullabilitySuffix.star ||
-          bound.nullabilitySuffix == NullabilitySuffix.star) {
-        newNullabilitySuffix = NullabilitySuffix.star;
-      } else {
-        newNullabilitySuffix = NullabilitySuffix.none;
-      }
-
-      var resolved = resolveToBound(bound) as TypeImpl;
-      return resolved.withNullability(newNullabilitySuffix);
-    }
-
-    return type;
-  }
-
-  DartType toLegacyType(DartType type) {
-    if (isNonNullableByDefault) return type;
-    return NullabilityEliminator.perform(typeProvider, type);
-  }
-
-  /// Tries to promote from the first type from the second type, and returns the
-  /// promoted type if it succeeds, otherwise null.
-  DartType tryPromoteToType(DartType to, DartType from);
-
-  /// Given a [DartType] type, return the [TypeParameterElement]s corresponding
-  /// to its formal type parameters (if any).
-  ///
-  /// @param type the type whose type arguments are to be returned
-  /// @return the type arguments associated with the given type
-  List<TypeParameterElement> typeFormalsAsElements(DartType type) {
-    if (type is FunctionType) {
-      return type.typeFormals;
-    } else if (type is InterfaceType) {
-      return type.element.typeParameters;
-    } else {
-      return const <TypeParameterElement>[];
-    }
-  }
-
-  /// Starting from the given [type], search its class hierarchy for types of
-  /// the form Future<R>, and return a list of the resulting R's.
-  List<DartType> _searchTypeHierarchyForFutureTypeParameters(DartType type) {
-    List<DartType> result = <DartType>[];
-    HashSet<ClassElement> visitedClasses = HashSet<ClassElement>();
-    void recurse(InterfaceTypeImpl type) {
-      if (type.isDartAsyncFuture && type.typeArguments.isNotEmpty) {
-        result.add(type.typeArguments[0]);
-      }
-      if (visitedClasses.add(type.element)) {
-        if (type.superclass != null) {
-          recurse(type.superclass);
-        }
-        for (InterfaceType interface in type.interfaces) {
-          recurse(interface);
-        }
-        visitedClasses.remove(type.element);
-      }
-    }
-
-    recurse(type);
-    return result;
-  }
-}
-
-/// The [public.TypeSystem] implementation.
-class TypeSystemImpl extends TypeSystem2 {
   /// False if implicit casts should always be disallowed.
   ///
   /// This affects the behavior of [isAssignableTo].
@@ -429,9 +49,6 @@
   /// This option is experimental and subject to change.
   bool strictInference;
 
-  @override
-  final TypeProviderImpl typeProvider;
-
   /// The cached instance of `Object?`.
   InterfaceTypeImpl _objectQuestion;
 
@@ -452,11 +69,10 @@
 
   TypeSystemImpl({
     @required this.implicitCasts,
-    @required bool isNonNullableByDefault,
+    @required this.isNonNullableByDefault,
     @required this.strictInference,
     @required TypeProvider typeProvider,
-  })  : typeProvider = typeProvider as TypeProviderImpl,
-        super(isNonNullableByDefault: isNonNullableByDefault) {
+  }) : typeProvider = typeProvider as TypeProviderImpl {
     _greatestLowerBoundHelper = GreatestLowerBoundHelper(this);
     _leastUpperBoundHelper = LeastUpperBoundHelper(this);
     _subtypeHelper = SubtypeHelper(this);
@@ -578,6 +194,65 @@
     return T;
   }
 
+  @override
+  TypeImpl flatten(DartType type) {
+    if (identical(type, UnknownInferredType.instance)) {
+      return type;
+    }
+
+    // if T is S? then flatten(T) = flatten(S)?
+    // if T is S* then flatten(T) = flatten(S)*
+    NullabilitySuffix nullabilitySuffix = type.nullabilitySuffix;
+    if (nullabilitySuffix != NullabilitySuffix.none) {
+      var S = (type as TypeImpl).withNullability(NullabilitySuffix.none);
+      return flatten(S).withNullability(nullabilitySuffix);
+    }
+
+    if (type is InterfaceType) {
+      // Implement the cases:
+      //  - "If T = FutureOr<S> then flatten(T) = S."
+      //  - "If T = Future<S> then flatten(T) = S."
+      if (type.isDartAsyncFutureOr || type.isDartAsyncFuture) {
+        return type.typeArguments.isNotEmpty
+            ? type.typeArguments[0]
+            : DynamicTypeImpl.instance;
+      }
+      // Implement the case: "Otherwise if T <: Future then let S be a type
+      // such that T << Future<S> and for all R, if T << Future<R> then S << R.
+      // Then flatten(T) = S."
+      //
+      // In other words, given the set of all types R such that T << Future<R>,
+      // let S be the most specific of those types, if any such S exists.
+      //
+      // Since we only care about the most specific type, it is sufficient to
+      // look at the types appearing as a parameter to Future in the type
+      // hierarchy of T.  We don't need to consider the supertypes of those
+      // types, since they are by definition less specific.
+      List<DartType> candidateTypes =
+          _searchTypeHierarchyForFutureTypeParameters(type);
+      DartType flattenResult =
+          InterfaceTypeImpl.findMostSpecificType(candidateTypes, this);
+      if (flattenResult != null) {
+        return flattenResult;
+      }
+    }
+    // Implement the case: "In any other circumstance, flatten(T) = T."
+    return type;
+  }
+
+  DartType futureOrBase(DartType type) {
+    // If `T` is `FutureOr<S>` for some `S`,
+    // then `futureOrBase(T)` = `futureOrBase(S)`
+    if (type is InterfaceType && type.isDartAsyncFutureOr) {
+      return futureOrBase(
+        type.typeArguments[0],
+      );
+    }
+
+    // Otherwise `futureOrBase(T)` = `T`.
+    return type;
+  }
+
   /// Compute "future value type" of [T].
   ///
   /// https://github.com/dart-lang/language/
@@ -613,6 +288,23 @@
     return objectQuestion;
   }
 
+  List<InterfaceType> gatherMixinSupertypeConstraintsForInference(
+      ClassElement mixinElement) {
+    List<InterfaceType> candidates;
+    if (mixinElement.isMixin) {
+      candidates = mixinElement.superclassConstraints;
+    } else {
+      candidates = [mixinElement.supertype];
+      candidates.addAll(mixinElement.mixins);
+      if (mixinElement.isMixinApplication) {
+        candidates.removeLast();
+      }
+    }
+    return candidates
+        .where((type) => type.element.typeParameters.isNotEmpty)
+        .toList();
+  }
+
   /// Given a type t, if t is an interface type with a call method defined,
   /// return the function type for the call method, otherwise return null.
   FunctionType getCallMethodType(DartType t) {
@@ -631,7 +323,6 @@
   ///
   /// https://github.com/dart-lang/language
   /// See `resources/type-system/upper-lower-bounds.md`
-  @override
   DartType getLeastUpperBound(DartType T1, DartType T2) {
     return _leastUpperBoundHelper.getLeastUpperBound(T1, T2);
   }
@@ -775,7 +466,6 @@
   /// https://github.com/dart-lang/sdk/issues/27526#issuecomment-260021397
   // TODO(scheglov) Move this method to elements for classes, typedefs,
   //  and generic functions; compute lazily and cache.
-  @override
   DartType instantiateToBounds(DartType type,
       {List<bool> hasError, Map<TypeParameterElement, DartType> knownTypes}) {
     List<TypeParameterElement> typeFormals = typeFormalsAsElements(type);
@@ -817,11 +507,28 @@
     }
   }
 
+  /// Given a [DartType] [type] and a list of types
+  /// [typeArguments], instantiate the type formals with the
+  /// provided actuals.  If [type] is not a parameterized type,
+  /// no instantiation is done.
+  DartType instantiateType(DartType type, List<DartType> typeArguments) {
+    if (type is FunctionType) {
+      return type.instantiate(typeArguments);
+    } else if (type is InterfaceTypeImpl) {
+      // TODO(scheglov) Use `ClassElement.instantiate()`, don't use raw types.
+      return type.element.instantiate(
+        typeArguments: typeArguments,
+        nullabilitySuffix: type.nullabilitySuffix,
+      );
+    } else {
+      return type;
+    }
+  }
+
   /// Given uninstantiated [typeFormals], instantiate them to their bounds.
   /// See the issue for the algorithm description.
   ///
   /// https://github.com/dart-lang/sdk/issues/27526#issuecomment-260021397
-  @override
   List<DartType> instantiateTypeFormalsToBounds(
       List<TypeParameterElement> typeFormals,
       {List<bool> hasError,
@@ -1135,8 +842,14 @@
     return false;
   }
 
-  @override
-  bool isMoreSpecificThan(DartType t1, DartType t2) => isSubtypeOf2(t1, t2);
+  /// Return `true` if the [leftType] is more specific than the [rightType]
+  /// (that is, if leftType << rightType), as defined in the Dart language spec.
+  ///
+  /// In strong mode, this is equivalent to [isSubtypeOf].
+  @Deprecated('Use isSubtypeOf() instead.')
+  bool isMoreSpecificThan(DartType leftType, DartType rightType) {
+    return isSubtypeOf2(leftType, rightType);
+  }
 
   /// Defines a total order on top and Object types.
   bool isMoreTop(DartType T, DartType S) {
@@ -1227,6 +940,23 @@
     return false;
   }
 
+  @override
+  bool isNonNullable(DartType type) {
+    if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
+      return false;
+    } else if (type is TypeParameterTypeImpl && type.promotedBound != null) {
+      return isNonNullable(type.promotedBound);
+    } else if (type.nullabilitySuffix == NullabilitySuffix.question) {
+      return false;
+    } else if (type is InterfaceType && type.isDartAsyncFutureOr) {
+      return isNonNullable(type.typeArguments[0]);
+    } else if (type is TypeParameterType) {
+      var bound = type.element.bound;
+      return bound != null && isNonNullable(bound);
+    }
+    return true;
+  }
+
   /// Return `true` for things in the equivalence class of `Null`.
   bool isNull(DartType type) {
     var typeImpl = type as TypeImpl;
@@ -1251,6 +981,20 @@
     return false;
   }
 
+  @override
+  bool isNullable(DartType type) {
+    if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
+      return true;
+    } else if (type is TypeParameterTypeImpl && type.promotedBound != null) {
+      return isNullable(type.promotedBound);
+    } else if (type.nullabilitySuffix == NullabilitySuffix.question) {
+      return true;
+    } else if (type.isDartAsyncFutureOr) {
+      return isNullable((type as InterfaceType).typeArguments[0]);
+    }
+    return false;
+  }
+
   /// Return `true` for any type which is in the equivalence class of `Object`.
   bool isObject(DartType type) {
     TypeImpl typeImpl = type;
@@ -1273,6 +1017,26 @@
     return false;
   }
 
+  @override
+  bool isPotentiallyNonNullable(DartType type) => !isNullable(type);
+
+  @override
+  bool isPotentiallyNullable(DartType type) => !isNonNullable(type);
+
+  @override
+  bool isStrictlyNonNullable(DartType type) {
+    if (type.isDynamic || type.isVoid || type.isDartCoreNull) {
+      return false;
+    } else if (type.nullabilitySuffix != NullabilitySuffix.none) {
+      return false;
+    } else if (type is InterfaceType && type.isDartAsyncFutureOr) {
+      return isStrictlyNonNullable(type.typeArguments[0]);
+    } else if (type is TypeParameterType) {
+      return isStrictlyNonNullable(type.bound);
+    }
+    return true;
+  }
+
   /// Check if [leftType] is a subtype of [rightType].
   ///
   /// Implements:
@@ -1361,6 +1125,62 @@
     }
   }
 
+  @override
+  DartType leastUpperBound(DartType leftType, DartType rightType) {
+    if (!NullSafetyUnderstandingFlag.isEnabled) {
+      leftType = NullabilityEliminator.perform(typeProvider, leftType);
+      rightType = NullabilityEliminator.perform(typeProvider, rightType);
+    }
+    return getLeastUpperBound(leftType, rightType);
+  }
+
+  /// Returns a nullable version of [type].  The result would be equivalent to
+  /// the union `type | Null` (if we supported union types).
+  DartType makeNullable(TypeImpl type) {
+    // TODO(paulberry): handle type parameter types
+    return type.withNullability(NullabilitySuffix.question);
+  }
+
+  /// Attempts to find the appropriate substitution for the [mixinElement]
+  /// type parameters that can be applied to [srcTypes] to make it equal to
+  /// [destTypes].  If no such substitution can be found, `null` is returned.
+  List<DartType> matchSupertypeConstraints(
+    ClassElement mixinElement,
+    List<DartType> srcTypes,
+    List<DartType> destTypes,
+  ) {
+    var typeParameters = mixinElement.typeParameters;
+    var inferrer = GenericInferrer(this, typeParameters);
+    for (int i = 0; i < srcTypes.length; i++) {
+      inferrer.constrainReturnType(srcTypes[i], destTypes[i]);
+      inferrer.constrainReturnType(destTypes[i], srcTypes[i]);
+    }
+
+    var inferredTypes = inferrer.infer(
+      typeParameters,
+      considerExtendsClause: false,
+    );
+    var substitution = Substitution.fromPairs(typeParameters, inferredTypes);
+
+    for (int i = 0; i < srcTypes.length; i++) {
+      var srcType = substitution.substituteType(srcTypes[i]);
+      var destType = destTypes[i];
+      if (isNonNullableByDefault) {
+        // TODO(scheglov) waiting for the spec
+        // https://github.com/dart-lang/sdk/issues/42605
+      } else {
+        srcType = toLegacyType(srcType);
+        destType = toLegacyType(destType);
+      }
+      if (srcType != destType) {
+        // Failed to find an appropriate substitution
+        return null;
+      }
+    }
+
+    return inferredTypes;
+  }
+
   /// Compute the canonical representation of [T].
   ///
   /// https://github.com/dart-lang/language
@@ -1369,7 +1189,45 @@
     return NormalizeHelper(this).normalize(T);
   }
 
+  /// Returns a non-nullable version of [type].  This is equivalent to the
+  /// operation `NonNull` defined in the spec.
   @override
+  DartType promoteToNonNull(DartType type) {
+    if (type.isDartCoreNull) return NeverTypeImpl.instance;
+
+    if (type is TypeParameterTypeImpl) {
+      var element = type.element;
+
+      // NonNull(X & T) = X & NonNull(T)
+      if (type.promotedBound != null) {
+        var promotedBound = promoteToNonNull(type.promotedBound);
+        return TypeParameterTypeImpl(
+          element: element,
+          nullabilitySuffix: NullabilitySuffix.none,
+          promotedBound: promotedBound,
+        );
+      }
+
+      // NonNull(X) = X & NonNull(B), where B is the bound of X
+      var promotedBound = element.bound != null
+          ? promoteToNonNull(element.bound)
+          : typeProvider.objectType;
+      if (identical(promotedBound, element.bound)) {
+        promotedBound = null;
+      }
+      return TypeParameterTypeImpl(
+        element: element,
+        nullabilitySuffix: NullabilitySuffix.none,
+        promotedBound: promotedBound,
+      );
+    }
+
+    return (type as TypeImpl).withNullability(NullabilitySuffix.none);
+  }
+
+  /// Determine the type of a binary expression with the given [operator] whose
+  /// left operand has the type [leftType] and whose right operand has the type
+  /// [rightType], given that resolution has so far produced the [currentType].
   DartType refineBinaryExpressionType(DartType leftType, TokenType operator,
       DartType rightType, DartType currentType, MethodElement operatorElement) {
     if (isNonNullableByDefault) {
@@ -1382,7 +1240,11 @@
     }
   }
 
-  @override
+  /// Determines the context type for the parameters of a method invocation
+  /// where the type of the target is [targetType], the method being invoked is
+  /// [methodElement], the context surrounding the method invocation is
+  /// [invocationContext], and the context type produced so far by resolution is
+  /// [currentType].
   DartType refineNumericInvocationContext(DartType targetType,
       Element methodElement, DartType invocationContext, DartType currentType) {
     if (methodElement is MethodElement && isNonNullableByDefault) {
@@ -1394,7 +1256,12 @@
     }
   }
 
-  @override
+  /// Determines the type of a method invocation where the type of the target is
+  /// [targetType], the method being invoked is [methodElement], the types of
+  /// the arguments passed to the method are [argumentTypes], and the type
+  /// produced so far by resolution is [currentType].
+  ///
+  /// TODO(scheglov) I expected that [methodElement] is [MethodElement].
   DartType refineNumericInvocationType(
       DartType targetType,
       Element methodElement,
@@ -1430,6 +1297,35 @@
     }
   }
 
+  @override
+  DartType resolveToBound(DartType type) {
+    if (type is TypeParameterTypeImpl) {
+      var element = type.element;
+
+      var bound = element.bound;
+      if (bound == null) {
+        return typeProvider.objectType;
+      }
+
+      NullabilitySuffix nullabilitySuffix = type.nullabilitySuffix;
+      NullabilitySuffix newNullabilitySuffix;
+      if (nullabilitySuffix == NullabilitySuffix.question ||
+          bound.nullabilitySuffix == NullabilitySuffix.question) {
+        newNullabilitySuffix = NullabilitySuffix.question;
+      } else if (nullabilitySuffix == NullabilitySuffix.star ||
+          bound.nullabilitySuffix == NullabilitySuffix.star) {
+        newNullabilitySuffix = NullabilitySuffix.star;
+      } else {
+        newNullabilitySuffix = NullabilitySuffix.none;
+      }
+
+      var resolved = resolveToBound(bound) as TypeImpl;
+      return resolved.withNullability(newNullabilitySuffix);
+    }
+
+    return type;
+  }
+
   /// Return `true` if runtime types [T1] and [T2] are equal.
   ///
   /// nnbd/feature-specification.md#runtime-type-equality-operator
@@ -1437,6 +1333,11 @@
     return RuntimeTypeEqualityHelper(this).equal(T1, T2);
   }
 
+  DartType toLegacyType(DartType type) {
+    if (isNonNullableByDefault) return type;
+    return NullabilityEliminator.perform(typeProvider, type);
+  }
+
   /// Merges two types into a single type.
   /// Compute the canonical representation of [T].
   ///
@@ -1447,7 +1348,8 @@
     return TopMergeHelper(this).topMerge(T, S);
   }
 
-  @override
+  /// Tries to promote from the first type from the second type, and returns the
+  /// promoted type if it succeeds, otherwise null.
   DartType tryPromoteToType(DartType to, DartType from) {
     // Allow promoting to a subtype, for example:
     //
@@ -1478,6 +1380,21 @@
     return null;
   }
 
+  /// Given a [DartType] type, return the [TypeParameterElement]s corresponding
+  /// to its formal type parameters (if any).
+  ///
+  /// @param type the type whose type arguments are to be returned
+  /// @return the type arguments associated with the given type
+  List<TypeParameterElement> typeFormalsAsElements(DartType type) {
+    if (type is FunctionType) {
+      return type.typeFormals;
+    } else if (type is InterfaceType) {
+      return type.element.typeParameters;
+    } else {
+      return const <TypeParameterElement>[];
+    }
+  }
+
   void updateOptions({
     @required bool implicitCasts,
     @required bool strictInference,
@@ -1785,6 +1702,30 @@
     // No special rules apply.
     return currentType;
   }
+
+  /// Starting from the given [type], search its class hierarchy for types of
+  /// the form Future<R>, and return a list of the resulting R's.
+  List<DartType> _searchTypeHierarchyForFutureTypeParameters(DartType type) {
+    List<DartType> result = <DartType>[];
+    HashSet<ClassElement> visitedClasses = HashSet<ClassElement>();
+    void recurse(InterfaceTypeImpl type) {
+      if (type.isDartAsyncFuture && type.typeArguments.isNotEmpty) {
+        result.add(type.typeArguments[0]);
+      }
+      if (visitedClasses.add(type.element)) {
+        if (type.superclass != null) {
+          recurse(type.superclass);
+        }
+        for (InterfaceType interface in type.interfaces) {
+          recurse(interface);
+        }
+        visitedClasses.remove(type.element);
+      }
+    }
+
+    recurse(type);
+    return result;
+  }
 }
 
 class _TypeVariableEliminator extends Substitution {
diff --git a/tools/VERSION b/tools/VERSION
index 5f4d7c5..e081728 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 10
 PATCH 0
-PRERELEASE 119
+PRERELEASE 120
 PRERELEASE_PATCH 0
\ No newline at end of file
