Version 2.0.0-dev.38.0

Merge commit '5c90b1fd98e767702357faa561193777527bd9c6' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2369ad0..fa39c4f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,5 @@
+## 2.0.0-dev.38.0
+
 ## 2.0.0-dev.37.0
 
 ### Tool Changes
diff --git a/docs/language/informal/dynamic-members.md b/docs/language/informal/dynamic-members.md
new file mode 100644
index 0000000..e60c925
--- /dev/null
+++ b/docs/language/informal/dynamic-members.md
@@ -0,0 +1,202 @@
+# Typing of members of dynamic
+
+Author: eernst@.
+
+Version: 0.1 (2018-03-13)
+
+Status: Under discussion.
+
+**This document** is a Dart 2 feature specification of the static typing
+of instance members of a receiver whose static type is `dynamic`.
+
+This document uses discussions in 
+[this github issue](https://github.com/dart-lang/sdk/issues/32414)
+as a starting point.
+
+
+## Motivation
+
+For Dart programs using a statically typed style, it is often helpful to
+use the most precise static type for an expression which is still sound.
+In contrast, if such an expression gets type `dynamic` it often causes
+subsequent type computations such as inference to make less useful
+decisions, or it may mask errors which are likely or guaranteed to occur at
+run time. Here is an example:
+
+```dart
+class A {
+  String toString([bool b = true]) =>
+      b ? 'This is an A!' : 'Whatever';
+}
+
+foo(List<String> xs) {
+  for (String s in xs) print(s);
+}
+
+main() {
+  dynamic d = new A();
+  var xs = [d.toString()];
+  foo(xs);
+}
+```
+
+In this example, the actual type argument passed to the list literal
+`[d.toString()]` by inference depends on the static type of the expression
+`d.toString()`. If that expression is given the type `dynamic` (as it would
+be in Dart 1) then the resulting list will be a `List<dynamic>`, and hence
+the invocation of `foo` would fail because it requires an argument of type
+`List<String>`.
+
+In general, a receiver with static type `dynamic` is assumed to have all
+members, i.e., we can make the attempt to invoke a getter, setter, method,
+or operator with any name, and we can pass any list of actual arguments and
+possibly some type arguments, and that will not cause any compile-time
+errors. Various checks may be performed at run time when such an invocation
+takes place, and that is the whole point: Usage of expressions of type
+`dynamic` allows developers to skip the static checks and instead have
+dynamic checks.
+
+However, every object in a Dart program execution has a type which is a
+subtype of `Object`. Hence, for each member declared by `Object`, it will
+either inherit an implementation declared by `Object`, or it will have some
+implementation specified as an override for the declaration in
+`Object`. Given that overriding declarations must satisfy certain
+constraints, we do know something about the properties of a member declared
+in `Object`. This allows static analysis to give static types to some
+expressions which are more precise than `dynamic`, even for a member access
+where the receiver has type `dynamic`, and that is the topic of this
+document.
+
+We will obey the general principle that an instance method invocation
+(including getters, setters, and operators) which would be compiled without
+errors under some typing of the receiver must also be without compile-time
+errors when the receiver has type `dynamic`. It should be noted that there
+is no requirement that the typing relies only on declarations which are in
+scope at the point where the invocation occurs, it must instead be possible
+to _declare_ such a class that the invocation can be statically typed. The
+point in obeying this principle is that dynamic invocation should be
+capable of performing _every_ invocation which is possible using types.
+
+For instance, `d.toString(42)` cannot have a compile-time error when `d`
+has static type `dynamic`, because we could have the following declaration,
+and `d` could have had type `D`:
+
+```dart
+class D {
+  noSuchMethod(Object o) => o;
+  Null toString([int i]) => null;
+}
+```
+
+Similarly, `d.noSuchMethod('Oh!')` would not be a compile-time error,
+because a contravariant type annotation on the parameter as shown above
+would allow actual arguments of other types than `Invocation`.
+
+On the other hand, it is safe to assign the static type `String` to
+`d.toString()`, because that invocation will definitely invoke the
+implementation of `toString` in `Object` or an override thereof, and that
+override must have a return type which is `String` or a subtype (for
+`String` that can only be `Null`, but in general it can be any subtype).
+
+It may look like a highly marginal corner of the language to give special
+treatment to the few methods declared in `Object`, but it does matter in
+practice that a number of invocations of `toString` are given the type
+`String`. Other members like `hashCode` get the same treatment in order to
+have a certain amount of consistency.
+
+Moreover, we have considered generalizing the notion of "the type dynamic"
+such that it becomes "the type dynamic based on `T`" for any given type
+`T`, using some syntax, e.g., `dynamic(T)`. The idea would be that
+statically known methods invoked on a receiver of type `dynamic(T)` would
+receive static checking, but invocations of other methods get dynamic
+checking. With that, the treatment specified in this document (which was
+originally motivated by the typing of `toString`) will suddenly apply to
+any member declared by `T`, where `T` can be any type (that is, any
+declarable member). It is then important to have a systematic approach and
+a simple conceptual "story" about how it works, and why it works like
+that. This document should be a usable starting point for such an approach
+and story.
+
+
+## Static Analysis
+
+In this section, `Object` denotes the built-in class `Object`, and
+`dynamic` denotes the built-in type `dynamic`.
+
+Let `e` be an expression of the form `d.g` where the static type of `d` is
+`dynamic` and `g` is a getter declared in `Object`; if the return type of
+`Object.g` is `T` then the static type of `e` is `T`.
+
+*For instance, `d.hashCode` has type `int` and `d.runtimeType` has type
+`Type`.*
+
+Let `e` be an expression of the form `d.m` where the static type of `d` is
+`dynamic` and `m` is a method declared in `Object` whose method signature
+has type `F` (*which is a function type*). The static type of `e` is then
+`F`.
+
+*For instance, `d.toString` has type `String Function()`.*
+
+Let `e` be an expression of the form `d.m(arguments)` where the static type
+of `d` is `dynamic`, `arguments` is an actual argument list, and `m` is a
+method declared in `Object` whose method signature has type `F`. If the
+number of positional actual arguments in `arguments` is less than the
+number of required positional arguments of `F` or greater than the number
+of positional arguments in `F`, or if `arguments` includes any named
+arguments with a name that is not declared in `F`, the type of `e` is
+`dynamic`. Otherwise, the type of `e` is the return type in `F`.
+
+*So `d.toString(bazzle: 42)` has type `dynamic` whereas `d.toString()` has
+type `String`. Note that invocations which "do not fit" the statically
+known declaration are not errors, they just get return type `dynamic`.*
+
+Let `e` be an expression of the form `d.m<typeArguments>(arguments)` where
+the static type of `d` is `dynamic`, `typeArguments` is a list of actual
+type arguments, `arguments` is an actual argument list, and `m` is a
+method declared in `Object` whose method signature has type `F`. The
+static type of `e` is then `dynamic`.
+
+*We do not need to address the case `d.m(arguments)` where `m` is a getter
+declared in `Object` whose return type is a function type or a supertype
+thereof, because no such getters exist, but such a case would be covered in
+a generalization to support `dynamic(T)` for all `T`. Similarly, such a
+generalization would need to handle the case where the method is generic
+and no type arguments are passed, and the case where the method is
+generic and a wrong number of type arguments is passed, etc. Such a
+generalization is expected to be possible without invalidating the rules
+given in this document.*
+
+For an instance method invocation `e` (including invocations of getters,
+setters, and operators) where the receiver has static type `dynamic` and
+`e` does not match any of the above cases, the static type of `e` is
+`dynamic`.
+
+*Note that it is not possible for an instance method invocation with a
+receiver of type `dynamic` to be a compile-time error (except, of course,
+that some expressions like `x[1, 2]` are syntax errors even though they
+could also be considered "invocations", and except that subexpressions are
+checked separately, and any given actual argument could be a compile-time
+error). In general, any argument list shape could be handled via
+`noSuchMethod`, and an argument of any type could be accepted because any
+formal parameter in an overriding declaration could have its type
+annotation contravariantly changed to `Object`. So it is a natural
+consequence of the principle mentioned in 'Motivation' that a `dynamic`
+receiver admits all instance method invocations.*
+
+
+## Dynamic Semantics
+
+This feature has no implications for the dynamic semantics, beyond the ones
+which are derived directly from the static typing.
+
+*For instance, a list literal may have a run-time type which is determined
+via inference by the static type of its elements, as in the example in the
+'Motivation' section, or the actual type argument may be influenced by the
+typing context, which may again depend on the rules specified in this
+document.*
+
+
+## Revisions
+
+- 0.1 (2018-03-13) Initial version, based on discussions in
+[this github issue](https://github.com/dart-lang/sdk/issues/32414).
diff --git a/docs/language/informal/generalized-void.md b/docs/language/informal/generalized-void.md
index 6b5718a..9c06e31 100644
--- a/docs/language/informal/generalized-void.md
+++ b/docs/language/informal/generalized-void.md
@@ -2,17 +2,15 @@
 
 **Author**: eernst@
 
+**Version**: 0.9 (2018-02-22)
+
 **Status**: Under implementation.
 
-**This document** is an informal specification of the generalized support
-in Dart 1.x for the type `void`. Dart 2 will have a very similar kind of
-generalized support for `void`, without the function type subtype exception
-that this feature includes for backward compatibility in Dart 1.x. This
-document specifies the feature for Dart 1.x and indicates how Dart 2
-differs at relevant points.
+**This document** is a feature specification of the generalized support
+in Dart 2 for the type `void`.
 
-**The feature** described here, *generalized void*, allows for using the
-type `void` as a type annotation and as a type argument.
+**The feature** described here, *generalized void*, allows for using
+`void` as a type annotation and as a type argument.
 
 The **motivation** for allowing the extended usage is that it helps
 developers state the intent that a particular **value should be
@@ -30,34 +28,34 @@
 like `Future<T>` and `Stream<T>`, and it uses `T` as a parameter type of a
 callback in the method `then`.
 
-Note that using the value of an expression of type `void` is not
+Note that using the value of an expression of type void is not
 technically dangerous, doing so does not violate any constraints at the
-level of the language semantics.  By using the type `void`, developers
+level of the language semantics.  By using the type void, developers
 indicate that the value of the corresponding expression evaluation is
 meaningless. Hence, there is **no requirement** for the generalized void
 mechanism to be strict and **sound**. However, it is the intention that the
 mechanism should be sufficiently sound to make the mechanism helpful and
 non-frustrating in practice.
 
-No constraints are imposed on which values may be given type `void`, so in
+No constraints are imposed on which values may be given type void, so in
 that sense `void` can be considered to be just another name for the type
 `Object`, flagged as useless. Note that this is an approximate rule in
 Dart 1.x, it fails to hold for function types; it does hold in Dart 2.
 
 The mechanisms helping developers to avoid using the value of an expression
-of type `void` are divided into **two phases**. This document specifies the
+of type void are divided into **two phases**. This document specifies the
 first phase.
 
 The **first phase** uses restrictions which are based on syntactic criteria
 in order to ensure that direct usage of the value of an expression of type
-`void` is a static warning (in Dart 2: an error). A few exceptions are
+void is a compile-time error. A few exceptions are
 allowed, e.g., type casts, such that developers can explicitly make the
 choice to use such a value. The general rule is that for every expression
-of type `void`, its value must be ignored.
+of type void, its value must be ignored.
 
 The **second phase** will deal with casts and preservation of
 voidness. Some casts will cause derived expressions to switch from having
-type `void` to having some other type, and hence those casts introduce the
+type void to having some other type, and hence those casts introduce the
 possibility that "a void value" will get passed and used. Here is an
 example:
 
@@ -88,7 +86,7 @@
 type ::= // ENTIRE RULE MODIFIED
     typeNotVoid | 'void'
 redirectingFactoryConstructorSignature ::=
-    'const'? 'factory' identifier ('.' identifier)? 
+    'const'? 'factory' identifier ('.' identifier)?
     formalParameterList `=' typeNotVoid ('.' identifier)?
 superclass ::=
     'extends' typeNotVoid
@@ -211,7 +209,7 @@
 are erased to regular function types during compilation. Hence there is no
 need to specify the the typing relations for generic function types. In
 Dart 2, the subtype relationship for generic function types follows from
-the rule that `void` is treated as `Object`.*
+the rule that the type void is treated as `Object`.*
 
 Consider a function type _T_ where the return type is the type void. In
 Dart 1.x, the dynamic more-specific-than relation, `<<`, and the dynamic
@@ -236,78 +234,108 @@
 Dart 2) then this assignment would be permitted (but we would then use
 voidness preservation to detect and avoid this situation at compile time).*
 
-*The semantics of checked mode checks involving types where the type void
+*The semantics of dynamic checks involving types where the type void
 occurs is determined by the semantics of subtype tests, so we do not
 specify that separately.*
 
-An instantiation of a generic class `G` is malbounded if it contains `void`
-as an actual type argument for a formal type parameter, unless that type
-parameter does not have a bound, or it has a bound which is the built-in
-class `Object`, or `dynamic`.
+It is a compile-time error to use `void` as the bound of a type variable.
+
+An instantiation of a generic class `G` is malbounded if it contains the
+type void as an actual type argument for a formal type parameter, unless
+that type parameter does not have a bound, or it has a bound which is the
+built-in class `Object`, or `dynamic`.
 
 *The treatment of malbounded types follows the current specification.*
 
+
 ## Static Analysis
 
-For the static analysis, the more-specific-than relation, `<<`, and the
-subtype relation, `<:`, are determined by the same rules as described above
-for the dynamic semantics, for both Dart 1.x and Dart 2.
+For the static analysis, the subtype relation, `<:`, is determined by the
+same rules as described above for the dynamic semantics.
 
-*That is, the type void is considered to be equivalent to the built-in
-class `Object` in Dart 1.x, except when used as a return type, in which
-case it is effectively considered to be a proper supertype of `Object`. In
-Dart 2 subtyping, the type void is consistently considered to be equivalent
-to the built-in class `Object`. As mentioned, this document does not
-specify voidness preservation; however, when voidness preservation checks
-are added we get an effect in Dart 2 which is similar to the special
-treatment of void as a return type in Dart 1.x: The function type downcast
-which will be rejected in Dart 1.x (at run time, with a static warning at
-compile time) will become a voidness preservation violation, i.e., a
-compile-time error.*
+*That is, the type void, for the purposes of subtyping, is considered to be
+equivalent to the built-in class `Object`. As mentioned, this document does
+not specify voidness preservation. However, when voidness preservation
+checks are added we will get (among other things) an effect which is
+similar to the special treatment of void as a return type which was used in
+Dart 1.x: In Dart 1.x, an implicit downcast from `void Function()` to
+`Object Function()` will fail at run time, but with voidness preservation
+it will be a compile-time error.*
 
-It is a static warning for an expression to have type void (in Dart 2: a
-compile-time error), except for the following situations:
+It is a compile-time error to evaluate an expression of type void, except
+for the following situations:
 
-*   In an expressionStatement `e;`, e may have type void.
+*   In an expressionStatement `e;`, `e` may have type void.
 *   In the initialization and increment expressions of a for-loop,
     `for (e1; e2; e3) {..}`, `e1` and `e3` may have type void.
-*   In a typeCast `e as T`, `e` may have type void.
+*   In a type cast `e as T`, `e` may have type void.
 *   In a parenthesized expression `(e)`, `e` may have type void.
+*   In a conditional expression `e ? e1 : e2`, `e1` and `e2` may have the
+    type void; the static type of the conditional expression is then the
+    type void. (*This is true even if one of the branches has a different
+    type.*)
+*   If _N1_ and _N2_ are non-terminals in the Dart grammar, and there is a
+    derivation of the form _N1 --> N2_, and _N2_ can have type void, then
+    _N1_ can also have type void for such a derivation. *In this derivation
+    no additional tokens are included, it is only the non-terminal which
+    changes.*
 *   In a return statement `return e;`, when the return type of the innermost
     enclosing function is the type void, `e` may have type void.
+*   An initializing expression for a variable of type void may have the type
+    void.
+*   An actual parameter expression corresponding to a formal parameter whose
+    statically known type annotation is the type void may have the type void.
+*   In an expression of the form `e1 = e2` where `e1` is an
+    assignableExpression denoting a variable or parameter of type void, `e2` may
+    have the type void.
+*   Assume that `e` is an expression ending in a `cascadeSection` of the
+    form `'..' S s = e1` where `S` is of the form `(cascadeSelector
+    argumentPart*) (assignableSelector argumentPart*)*` and `e1` is an
+    `expressionWithoutCascade`. If `s` is an `assignableSelector` of the
+    form `'.' identifier` or `'?.' identifier` where the static type of the
+    `identifier` is the type void, `e1` may have type void; otherwise, if
+    `s` is an `assignableSelector` of the form `'[' e0 ']'` where the
+    static type of the first formal parameter in the statically known
+    declaration of operator `[]=` is the type void, `e0` may have type
+    void; also, if the static type of the second formal parameter is the
+    type void, `e1` may have type void.
 
-*Note that the parenthesized expression itself has type void, so it is
-again subject to the same constraints. Also note that we may not allow
-return statements returning an expression of type void in Dart 2, but
-it is allowed here for backward compatibility.*
+*The rule about non-terminals is needed in order to allow, say, `void x = b
+? (y) : e2;` where `y` has type void: `y` is an identifier which is derived
+from primary, which is derived from postfixExpression, from
+unaryExpression, from multiplicativeExpression, etc. Only if we allow such
+a (trivial) multiplicativeExpression can we allow the corresponding
+(trivial) unaryExpression, etc., all the way down to identifier, and all
+the way up to expression, which is needed for the initialization of `x`.*
 
-*The value yielded by an expression of type void must be discarded (and
-hence ignored), except when explicitly subjected to a type cast. This
+*The general rule is that the value yielded by an expression of type void
+must be discarded (and hence ignored), except when explicitly subjected to
+a type cast, or when returned or assigned to a target of type void. This
 "makes it hard to use a meaningless value", but leaves a small escape hatch
 open for the cases where the developer knows that the typing misrepresents
 the actual situation.*
 
-It is a static warning (in Dart 2: a compile-time error) if a return
-statement `return e;` occurs such that the innermost enclosing function
-has return type `void` and the static type of `e` is not the type void.
+It is a compile-time error if a return statement `return e;` occurs such
+that the innermost enclosing function has return type `void` and the static
+type of `e` is not the type void.
 
-It is a static warning (in Dart 2: a compile-time error) if a function
-marked `async*`, or `sync*` has return type `void`.
+It is a compile-time error if a function marked `async*`, or `sync*` has
+return type `void`.
 
 *Note that it is allowed for an `async` function to have return type
 `void`. This serves to indicate that said function performs a
 "fire-and-forget" operation, that is, it is not even useful for the caller
 to synchronize with the completion of that task.*
 
-It is a static warning (Dart 2: a compile-time error) for a for-in
-statement to have an iterator expression of type `T` such that
-`Iterator<void>` is the most specific instantiation of `Iterator` that is a
-superinterface of `T`, unless the iteration variable has type void.
+It is a compile-time error for a for-in statement to have an iterator
+expression of type `T` such that `Iterator<void>` is the most specific
+instantiation of `Iterator` that is a superinterface of `T`, unless the
+iteration variable has type void.
 
-It is a static warning (Dart 2: a compile-time error) for an asynchronous
-for-in statement to have a stream expression of type `T` such that
-`Stream<void>` is the most specific instantiation of `Stream` that is a
-superinterface of `T`, unless the iteration variable has type void.
+It is a compile-time error for an asynchronous for-in statement to have a
+stream expression of type `T` such that `Stream<void>` is the most specific
+instantiation of `Stream` that is a superinterface of `T`, unless the
+iteration variable has type void.
 
 *Hence, `for (Object x in <void>[]) {}` and
 `await for (int x in new Stream<void>.empty()) {}` are errors, whereas
@@ -320,13 +348,16 @@
 void. In this case, the bound is considered to be the built-in class
 `Object`.
 
-In Dart 2, it is a compile-time error when a method declaration _D2_ with
-return type void overrides a method declaration _D1_ whose return type is
-not void.
+It is a compile-time error when a method declaration _D2_ with return type
+void overrides a method declaration _D1_ whose return type is not void.
 
-*This rule is a special case of voidness preservation, which is needed in
-order to maintain the discipline which arises naturally from the function
-type subtype rules in Dart 1.x concerning void as a return type.*
+*This rule is a special case of voidness preservation, which maintains the
+discipline which arises naturally from the function type subtype rules in
+Dart 1.x concerning void as a return type. It also matches the conceptual
+interpretation that a value of type void can be anything, but it should be
+discarded: This ensures that a subtype can be used where the supertype is
+expected (also known as Liskov substitutability), because it is always
+considered safe to ignore the value of an expression evaluation.*
 
 ## Discussion
 
@@ -356,6 +387,12 @@
 
 ## Updates
 
+*   February 22nd 2018, v0.9: Added several new contexts where an
+    expression with static type void may be evaluated, such that pure data
+    transfers to a target of type void are allowed. For instance, a void
+    expression may be passed as an actual argument to a parameter of type
+    void.
+
 *   August 22nd 2017: Reworded specification of reified types to deal with
     only such values which may be obtained at run time (previously mentioned
     some entities which may not exist). Added one override rule.
diff --git a/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart b/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart
index 88bdde6..9340caf 100644
--- a/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart
@@ -114,16 +114,16 @@
   /// Each value is the compilation result of the key library.
   final Map<Uri, LibraryCompilationResult> _results = {};
 
-  /// The [Program] with currently valid libraries. When a file is invalidated,
-  /// we remove the file, its library, and everything affected from [_program].
-  Program _program = new Program();
+  /// The [Component] with currently valid libraries. When a file is invalidated,
+  /// we remove the file, its library, and everything affected from [_component].
+  Component _component = new Component();
 
   /// Each key is the file system URI of a library.
   /// Each value is the libraries that directly depend on the key library.
   final Map<Uri, Set<Uri>> _directLibraryDependencies = {};
 
   /// Each key is the file system URI of a library.
-  /// Each value is the [Library] that is still in the [_program].
+  /// Each value is the [Library] that is still in the [_component].
   final Map<Uri, Library> _uriToLibrary = {};
 
   /// Each key is the file system URI of a part.
@@ -227,9 +227,9 @@
         var dillTarget =
             new DillTarget(_options.ticker, uriTranslator, _options.target);
 
-        // Append all libraries what we still have in the current program.
+        // Append all libraries what we still have in the current component.
         await _logger.runAsync('Load dill libraries', () async {
-          dillTarget.loader.appendLibraries(_program);
+          dillTarget.loader.appendLibraries(_component);
           await dillTarget.buildOutlines();
         });
 
@@ -238,23 +238,23 @@
             uriTranslator, new AnalyzerMetadataCollector());
         kernelTarget.read(uri);
 
-        // Compile the entry point into the new program.
-        _program = await _logger.runAsync('Compile', () async {
-          await kernelTarget.buildOutlines(nameRoot: _program.root);
-          return await kernelTarget.buildProgram() ?? _program;
+        // Compile the entry point into the new component.
+        _component = await _logger.runAsync('Compile', () async {
+          await kernelTarget.buildOutlines(nameRoot: _component.root);
+          return await kernelTarget.buildComponent() ?? _component;
         });
 
         // TODO(scheglov) Only for new libraries?
-        _program.computeCanonicalNames();
+        _component.computeCanonicalNames();
 
         _logger.run('Compute dependencies', _computeDependencies);
 
         // TODO(scheglov) Can we keep the same instance?
         var types = new TypeEnvironment(
-            new CoreTypes(_program), new ClassHierarchy(_program));
+            new CoreTypes(_component), new ClassHierarchy(_component));
 
         // Add results for new libraries.
-        for (var library in _program.libraries) {
+        for (var library in _component.libraries) {
           if (!_results.containsKey(library.importUri)) {
             Map<Uri, List<CollectedResolution>> libraryResolutions =
                 kernelTarget.resolutions[library.fileUri];
@@ -276,7 +276,7 @@
             }
 
             var libraryResult = new LibraryCompilationResult(
-                _program, types, library.importUri, library, files);
+                _component, types, library.importUri, library, files);
             _results[library.importUri] = libraryResult;
           }
         }
@@ -299,9 +299,9 @@
       if (library == null) return;
 
       // Invalidate the library.
-      _program.libraries.remove(library);
-      _program.root.removeChild('${library.importUri}');
-      _program.uriToSource.remove(libraryUri);
+      _component.libraries.remove(library);
+      _component.root.removeChild('${library.importUri}');
+      _component.uriToSource.remove(libraryUri);
       _results.remove(library.importUri);
 
       // Recursively invalidate dependencies.
@@ -314,7 +314,7 @@
     invalidateLibrary(libraryUri);
   }
 
-  /// Recompute [_directLibraryDependencies] for the current [_program].
+  /// Recompute [_directLibraryDependencies] for the current [_component].
   void _computeDependencies() {
     _directLibraryDependencies.clear();
     _uriToLibrary.clear();
@@ -341,8 +341,8 @@
       }
     }
 
-    // Record dependencies for every library in the program.
-    _program.libraries.forEach(processLibrary);
+    // Record dependencies for every library in the component.
+    _component.libraries.forEach(processLibrary);
   }
 
   Future<T> _runWithFrontEndContext<T>(String msg, Future<T> f()) async {
@@ -355,13 +355,13 @@
 
 /// The compilation result for a single library.
 class LibraryCompilationResult {
-  /// The full current [Program]. It has all libraries that are required by
+  /// The full current [Component]. It has all libraries that are required by
   /// this library, but might also have other libraries, that are not required.
   ///
   /// The object is mutable, and is changed when files are invalidated.
-  final Program program;
+  final Component component;
 
-  /// The [TypeEnvironment] for the [program].
+  /// The [TypeEnvironment] for the [component].
   final TypeEnvironment types;
 
   /// The absolute URI of the library.
@@ -374,7 +374,7 @@
   final Map<Uri, FileCompilationResult> files;
 
   LibraryCompilationResult(
-      this.program, this.types, this.uri, this.kernel, this.files);
+      this.component, this.types, this.uri, this.kernel, this.files);
 }
 
 /// The [DietListener] that record resolution information.
diff --git a/pkg/analyzer/lib/src/dart/analysis/kernel_context.dart b/pkg/analyzer/lib/src/dart/analysis/kernel_context.dart
index e0323b2..0ce8c48 100644
--- a/pkg/analyzer/lib/src/dart/analysis/kernel_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/kernel_context.dart
@@ -88,7 +88,7 @@
       // This is probably OK, because we consume them lazily.
       var libraryMap = <String, kernel.Library>{};
       var libraryExistMap = <String, bool>{};
-      for (var library in compilationResult.program.libraries) {
+      for (var library in compilationResult.component.libraries) {
         String uriStr = library.importUri.toString();
         libraryMap[uriStr] = library;
         FileState file = fsState.getFileForUri(library.importUri);
diff --git a/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart b/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart
index 9ec5360..f96c5c6 100644
--- a/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/kernel_metadata.dart
@@ -21,7 +21,7 @@
   /// Return the [AnalyzerMetadata] for the [node], or `null` absent.
   static AnalyzerMetadata forNode(kernel.TreeNode node) {
     var repository =
-        node.enclosingProgram.metadata[AnalyzerMetadataRepository.TAG];
+        node.enclosingComponent.metadata[AnalyzerMetadataRepository.TAG];
     if (repository != null) {
       return repository.mapping[node];
     }
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 5823b35..083a05f 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -45,7 +45,8 @@
         messageMissingAssignableSelector,
         messageNativeClauseShouldBeAnnotation,
         messageStaticConstructor,
-        templateDuplicateLabelInSwitchStatement;
+        templateDuplicateLabelInSwitchStatement,
+        templateExpectedType;
 import 'package:front_end/src/fasta/kernel/kernel_builder.dart'
     show Builder, KernelLibraryBuilder, Scope;
 import 'package:front_end/src/fasta/quote.dart';
@@ -897,6 +898,17 @@
     debugEvent("AsOperator");
 
     TypeAnnotation type = pop();
+    if (type is TypeName) {
+      Identifier name = type.name;
+      if (name is SimpleIdentifier) {
+        if (name.name == 'void') {
+          Token token = name.beginToken;
+          // TODO(danrubel): This needs to be reported during fasta resolution.
+          handleRecoverableError(
+              templateExpectedType.withArguments(token), token, token);
+        }
+      }
+    }
     Expression expression = pop();
     push(ast.asExpression(expression, asOperator, type));
   }
@@ -929,6 +941,17 @@
     debugEvent("IsOperator");
 
     TypeAnnotation type = pop();
+    if (type is TypeName) {
+      Identifier name = type.name;
+      if (name is SimpleIdentifier) {
+        if (name.name == 'void') {
+          Token token = name.beginToken;
+          // TODO(danrubel): This needs to be reported during fasta resolution.
+          handleRecoverableError(
+              templateExpectedType.withArguments(token), token, token);
+        }
+      }
+    }
     Expression expression = pop();
     push(ast.isExpression(expression, isOperator, not, type));
   }
diff --git a/pkg/analyzer/lib/src/kernel/loader.dart b/pkg/analyzer/lib/src/kernel/loader.dart
index 24808f0..73dd076 100644
--- a/pkg/analyzer/lib/src/kernel/loader.dart
+++ b/pkg/analyzer/lib/src/kernel/loader.dart
@@ -90,7 +90,7 @@
 }
 
 class DartLoader implements ReferenceLevelLoader {
-  final ast.Program program;
+  final ast.Component component;
   final ApplicationRoot applicationRoot;
   final Bimap<ClassElement, ast.Class> _classes =
       new Bimap<ClassElement, ast.Class>();
@@ -119,7 +119,7 @@
 
   bool get strongMode => context.analysisOptions.strongMode;
 
-  DartLoader(this.program, DartOptions options, Packages packages,
+  DartLoader(this.component, DartOptions options, Packages packages,
       {DartSdk dartSdk,
       AnalysisContext context,
       this.ignoreRedirectingFactories: true})
@@ -145,7 +145,7 @@
         ..isExternal = true
         ..name = getLibraryName(element)
         ..fileUri = element.source.uri;
-      program.libraries.add(library..parent = program);
+      component.libraries.add(library..parent = component);
       _libraries[element] = library;
     }
     return library;
@@ -732,7 +732,7 @@
     }
   }
 
-  void loadSdkInterface(ast.Program program, Target target) {
+  void loadSdkInterface(ast.Component component, Target target) {
     var requiredSdkMembers = target.requiredSdkClasses;
     for (var libraryUri in requiredSdkMembers.keys) {
       var source = context.sourceFactory.forUri2(Uri.parse(libraryUri));
@@ -764,8 +764,8 @@
         }
       }
     }
-    for (int i = 0; i < program.libraries.length; ++i) {
-      var library = program.libraries[i];
+    for (int i = 0; i < component.libraries.length; ++i) {
+      var library = component.libraries[i];
       if (compileSdk || library.importUri.scheme != 'dart') {
         ensureLibraryIsLoaded(library);
       }
@@ -777,7 +777,7 @@
   /// This operation may be expensive and should only be used for diagnostics.
   List<String> getLoadedFileNames() {
     var list = <String>[];
-    for (var library in program.libraries) {
+    for (var library in component.libraries) {
       LibraryElement element = context.computeLibraryElement(context
           .sourceFactory
           .forUri2(applicationRoot.absoluteUri(library.importUri)));
@@ -829,14 +829,14 @@
         new ast.Name('main'),
         ast.ProcedureKind.Method,
         new ast.FunctionNode(new ast.ExpressionStatement(new ast.Throw(
-            new ast.StringLiteral('Program has no main method')))),
+            new ast.StringLiteral('Component has no main method')))),
         isStatic: true)
       ..fileUri = library.fileUri;
     library.addMember(main);
     return main;
   }
 
-  void loadProgram(Uri mainLibrary, {Target target, bool compileSdk}) {
+  void loadComponent(Uri mainLibrary, {Target target, bool compileSdk}) {
     ast.Library library = getLibraryReferenceFromUri(mainLibrary);
     ensureLibraryIsLoaded(library);
     var mainMethod = _getMainMethod(mainLibrary);
@@ -844,7 +844,7 @@
     if (mainMethod == null) {
       mainMethod = _makeMissingMainMethod(library);
     }
-    program.mainMethod = mainMethod;
+    component.mainMethod = mainMethod;
     for (LibraryElement libraryElement in libraryElements) {
       for (CompilationUnitElement compilationUnitElement
           in libraryElement.units) {
@@ -858,7 +858,7 @@
           // The source's contents could not be accessed.
           sourceCode = const <int>[];
         }
-        program.uriToSource[source.uri] =
+        component.uriToSource[source.uri] =
             new ast.Source(lineInfo.lineStarts, sourceCode);
       }
     }
@@ -896,7 +896,7 @@
   String lastPackagePath;
   bool lastStrongMode;
 
-  Future<DartLoader> getLoader(ast.Program program, DartOptions options,
+  Future<DartLoader> getLoader(ast.Component component, DartOptions options,
       {String packageDiscoveryPath}) async {
     if (dartSdk == null ||
         lastSdk != options.sdk ||
@@ -912,7 +912,7 @@
       packages = await createPackages(options.packagePath,
           discoveryPath: packageDiscoveryPath);
     }
-    return new DartLoader(program, options, packages, dartSdk: dartSdk);
+    return new DartLoader(component, options, packages, dartSdk: dartSdk);
   }
 }
 
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 5d3baf4..b3465ea 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -191,31 +191,6 @@
 
   @override
   @failingTest
-  void test_expectedTypeName_as_void() {
-    // TODO(brianwilkerson) Does not recover.
-    //   Expected: true
-    //   Actual: <false>
-    //
-    //   package:test                                                       expect
-    //   test/generated/parser_fasta_test.dart 2974:5                       ParserProxy._run
-    //   test/generated/parser_fasta_test.dart 2661:34                      FastaParserTestCase._runParser
-    super.test_expectedTypeName_as_void();
-  }
-
-  @override
-  @failingTest
-  void test_expectedTypeName_is_void() {
-    // TODO(brianwilkerson) Does not recover.
-    //   Expected: true
-    //   Actual: <false>
-    //
-    //   package:test                                                       expect
-    //   test/generated/parser_fasta_test.dart 2999:5                       ParserProxy._run
-    super.test_expectedTypeName_is_void();
-  }
-
-  @override
-  @failingTest
   void test_getterInFunction_block_noReturnType() {
     // TODO(brianwilkerson) Does not recover.
     //   type 'ExpressionStatementImpl' is not a subtype of type 'FunctionDeclarationStatement' of 'statement' where
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index dfab7a0..353465d 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -3219,7 +3219,7 @@
   void test_expectedTypeName_is_void() {
     parseExpression("x is void)",
         expectedEndOffset: 9,
-        errors: [expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 4, 4)]);
+        errors: [expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 5, 4)]);
   }
 
   void test_exportAsType() {
@@ -3795,6 +3795,52 @@
     ]);
   }
 
+  void test_initializedVariableInForEach_var() {
+    Statement statement = parseStatement('for (var a = 0 in foo) {}');
+    expectNotNullIfNoErrors(statement);
+    listener.assertErrors([
+      expectedError(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, 11, 1)
+    ]);
+  }
+
+  void test_initializedVariableInForEach_annotation() {
+    Statement statement = parseStatement('for (@Foo var a = 0 in foo) {}');
+    expectNotNullIfNoErrors(statement);
+    listener.assertErrors([
+      expectedError(ParserErrorCode.INITIALIZED_VARIABLE_IN_FOR_EACH, 16, 1)
+    ]);
+  }
+
+  void test_initializedVariableInForEach_localFunction() {
+    Statement statement = parseStatement('for (f()) {}');
+    expectNotNullIfNoErrors(statement);
+    listener.assertErrors(usingFastaParser
+        ? [
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 8, 1),
+            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 8, 1)
+          ]
+        : [
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 7, 1),
+            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 8, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 8, 1)
+          ]);
+  }
+
+  void test_initializedVariableInForEach_localFunction2() {
+    Statement statement = parseStatement('for (T f()) {}');
+    expectNotNullIfNoErrors(statement);
+    listener.assertErrors(usingFastaParser
+        ? [
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 7, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1)
+          ]
+        : [
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 5, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 1)
+          ]);
+  }
+
   void test_invalidAwaitInFor() {
     Statement statement = parseStatement('await for (; ;) {}');
     expectNotNullIfNoErrors(statement);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
index 952d08c..fcc0791 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
@@ -401,7 +401,7 @@
     // Remember Kernel libraries produced by the compiler.
     var libraryMap = <String, kernel.Library>{};
     var libraryExistMap = <String, bool>{};
-    for (var library in libraryResult.program.libraries) {
+    for (var library in libraryResult.component.libraries) {
       String uriStr = library.importUri.toString();
       libraryMap[uriStr] = library;
       FileState file = fsState.getFileForUri(library.importUri);
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index ab0a2ae..326e6a0 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -323,7 +323,7 @@
 }
 
 /**
- * A node representing a resolved element of the program. The kind of
+ * A node representing a resolved element of the component. The kind of
  * elements that need an [ElementTypeInformation] are:
  *
  * - Functions (including getters and setters)
diff --git a/pkg/compiler/lib/src/io/kernel_source_information.dart b/pkg/compiler/lib/src/io/kernel_source_information.dart
index 93d324e..586b0f7 100644
--- a/pkg/compiler/lib/src/io/kernel_source_information.dart
+++ b/pkg/compiler/lib/src/io/kernel_source_information.dart
@@ -90,7 +90,7 @@
     ir.Location location;
     if (offset != null) {
       location = node.location;
-      location = node.enclosingProgram.getLocation(location.file, offset);
+      location = node.enclosingComponent.getLocation(location.file, offset);
     } else {
       while (node != null && node.fileOffset == ir.TreeNode.noOffset) {
         node = node.parent;
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index db3de60..ba98796 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -69,7 +69,7 @@
       {void logger(String msg)}) {}
 
   @override
-  void performGlobalTransformations(CoreTypes coreTypes, Program program,
+  void performGlobalTransformations(CoreTypes coreTypes, Component component,
       {void logger(String msg)}) {}
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index bfb8531..cc058e6 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -126,11 +126,11 @@
 abstract class KernelToElementMapForImpact extends KernelToElementMap {
   NativeBasicData get nativeBasicData;
 
-  /// Adds libraries in [program] to the set of libraries.
+  /// Adds libraries in [component] to the set of libraries.
   ///
-  /// The main method of the first program is used as the main method for the
+  /// The main method of the first component is used as the main method for the
   /// compilation.
-  void addProgram(ir.Program program);
+  void addProgram(ir.Component component);
 
   /// Returns the [ConstructorEntity] corresponding to a super initializer in
   /// [constructor].
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 53b132c..ccec600 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -1216,12 +1216,12 @@
   @override
   NativeBasicData get nativeBasicData => _frontendStrategy.nativeBasicData;
 
-  /// Adds libraries in [program] to the set of libraries.
+  /// Adds libraries in [component] to the set of libraries.
   ///
-  /// The main method of the first program is used as the main method for the
+  /// The main method of the first component is used as the main method for the
   /// compilation.
-  void addProgram(ir.Program program) {
-    _env.addProgram(program);
+  void addProgram(ir.Component component) {
+    _env.addProgram(component);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 782c999..0870b99 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -23,25 +23,25 @@
 import 'element_map_mixins.dart';
 import 'kelements.dart' show KImport;
 
-/// Environment for fast lookup of program libraries.
+/// Environment for fast lookup of component libraries.
 class ProgramEnv {
-  final Set<ir.Program> _programs = new Set<ir.Program>();
+  final Set<ir.Component> _programs = new Set<ir.Component>();
 
   Map<Uri, LibraryEnv> _libraryMap;
 
   /// TODO(johnniwinther): Handle arbitrary load order if needed.
   ir.Member get mainMethod => _programs.first?.mainMethod;
 
-  void addProgram(ir.Program program) {
-    if (_programs.add(program)) {
+  void addProgram(ir.Component component) {
+    if (_programs.add(component)) {
       if (_libraryMap != null) {
-        _addLibraries(program);
+        _addLibraries(component);
       }
     }
   }
 
-  void _addLibraries(ir.Program program) {
-    for (ir.Library library in program.libraries) {
+  void _addLibraries(ir.Component component) {
+    for (ir.Library library in component.libraries) {
       _libraryMap[library.importUri] = new LibraryEnv(library);
     }
   }
@@ -49,8 +49,8 @@
   void _ensureLibraryMap() {
     if (_libraryMap == null) {
       _libraryMap = <Uri, LibraryEnv>{};
-      for (ir.Program program in _programs) {
-        _addLibraries(program);
+      for (ir.Component component in _programs) {
+        _addLibraries(component);
       }
     }
   }
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index a2d7c31..ace0223 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -815,8 +815,7 @@
   }
 }
 
-/// A loader that builds a kernel IR representation of the program (or set of
-/// libraries).
+/// A loader that builds a kernel IR representation of the component.
 ///
 /// It supports loading both .dart source files or pre-compiled .dill files.
 /// When given .dart source files, it invokes the shared frontend
@@ -832,7 +831,7 @@
   final api.CompilerInput compilerInput;
 
   /// Holds the mapping of Kernel IR to KElements that is constructed as a
-  /// result of loading a program.
+  /// result of loading a component.
   final KernelToElementMapForImpactImpl _elementMap;
 
   final bool verbose;
@@ -847,7 +846,7 @@
       : _allLoadedLibraries = new List<LibraryEntity>(),
         super(measurer);
 
-  /// Loads an entire Kernel [Program] from a file on disk (note, not just a
+  /// Loads an entire Kernel [Component] from a file on disk (note, not just a
   /// library, so this name is actually a bit of a misnomer).
   // TODO(efortuna): Rename this once the Element library loader class goes
   // away.
@@ -855,12 +854,12 @@
       {bool skipFileWithPartOfTag: false}) {
     return measure(() async {
       var isDill = resolvedUri.path.endsWith('.dill');
-      ir.Program program;
+      ir.Component component;
       if (isDill) {
         api.Input input = await compilerInput.readFromUri(resolvedUri,
             inputKind: api.InputKind.binary);
-        program = new ir.Program();
-        new BinaryBuilder(input.data).readProgram(program);
+        component = new ir.Component();
+        new BinaryBuilder(input.data).readComponent(component);
       } else {
         bool strongMode = _elementMap.options.strongMode;
         String platform = strongMode
@@ -871,28 +870,28 @@
             new Dart2jsTarget(new TargetFlags(strongMode: strongMode)),
             platformBinaries.resolve(platform),
             _packageConfig);
-        program = await fe.compile(
+        component = await fe.compile(
             initializedCompilerState,
             verbose,
             new CompilerFileSystem(compilerInput),
             (e) => reportFrontEndMessage(reporter, e),
             resolvedUri);
       }
-      if (program == null) return null;
-      return createLoadedLibraries(program);
+      if (component == null) return null;
+      return createLoadedLibraries(component);
     });
   }
 
   // Only visible for unit testing.
-  LoadedLibraries createLoadedLibraries(ir.Program program) {
-    _elementMap.addProgram(program);
+  LoadedLibraries createLoadedLibraries(ir.Component component) {
+    _elementMap.addProgram(component);
     LibraryEntity rootLibrary = null;
-    Iterable<ir.Library> libraries = program.libraries;
-    if (program.mainMethod != null) {
-      var root = program.mainMethod.enclosingLibrary;
+    Iterable<ir.Library> libraries = component.libraries;
+    if (component.mainMethod != null) {
+      var root = component.mainMethod.enclosingLibrary;
       rootLibrary = _elementMap.lookupLibrary(root.importUri);
 
-      // Filter unreachable libraries: [Program] was built by linking in the
+      // Filter unreachable libraries: [Component] was built by linking in the
       // entire SDK libraries, not all of them are used. We include anything
       // that is reachable from `main`. Note that all internal libraries that
       // the compiler relies on are reachable from `dart:core`.
@@ -907,7 +906,7 @@
       search(root);
 
       // Libraries dependencies do not show implicit imports to `dart:core`.
-      var dartCore = program.libraries.firstWhere((lib) {
+      var dartCore = component.libraries.firstWhere((lib) {
         return lib.importUri.scheme == 'dart' && lib.importUri.path == 'core';
       });
       search(dartCore);
diff --git a/pkg/compiler/tool/generate_kernel.dart b/pkg/compiler/tool/generate_kernel.dart
index 9887aaa..a649997 100644
--- a/pkg/compiler/tool/generate_kernel.dart
+++ b/pkg/compiler/tool/generate_kernel.dart
@@ -40,8 +40,8 @@
   }
 
   Uri entry = Uri.base.resolve(nativeToUriPath(flags.rest.first));
-  var program = await kernelForProgram(entry, options);
-  await writeProgramToBinary(program, flags['out']);
+  var component = await kernelForProgram(entry, options);
+  await writeComponentToBinary(component, flags['out']);
 }
 
 ArgParser _argParser = new ArgParser()
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index f3f1108..810aa8e 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -197,12 +197,12 @@
   if (!file.parent.existsSync()) file.parent.createSync(recursive: true);
 
   // Useful for debugging:
-  writeProgramToText(result.program, path: output + '.txt');
+  writeComponentToText(result.component, path: output + '.txt');
 
   // TODO(jmesserly): Save .dill file so other modules can link in this one.
-  //await writeProgramToBinary(program, output);
+  //await writeComponentToBinary(component, output);
   var jsModule = compileToJSModule(
-      result.program, result.inputSummaries, summaryUris, declaredVariables);
+      result.component, result.inputSummaries, summaryUris, declaredVariables);
   var jsCode = jsProgramToCode(jsModule, moduleFormat,
       buildSourceMap: argResults['source-map'] as bool,
       jsUrl: path.toUri(output).toString(),
@@ -219,7 +219,7 @@
   return new CompilerResult(compilerState, true);
 }
 
-JS.Program compileToJSModule(Program p, List<Program> summaries,
+JS.Program compileToJSModule(Component p, List<Component> summaries,
     List<Uri> summaryUris, Map<String, String> declaredVariables) {
   var compiler = new ProgramCompiler(p, declaredVariables: declaredVariables);
   return compiler.emitProgram(p, summaries, summaryUris);
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 9e7b386..d3f8a9f 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -44,10 +44,10 @@
 
   /// Maps a library URI import, that is not in [_libraries], to the
   /// corresponding Kernel summary module we imported it with.
-  final _importToSummary = new Map<Library, Program>.identity();
+  final _importToSummary = new Map<Library, Component>.identity();
 
   /// Maps a summary to the file URI we used to load it from disk.
-  final _summaryToUri = new Map<Program, Uri>.identity();
+  final _summaryToUri = new Map<Component, Uri>.identity();
 
   /// Imported libraries, and the temporaries used to refer to them.
   final _imports = new Map<Library, JS.TemporaryId>();
@@ -92,7 +92,7 @@
   /// The current source file URI for emitting in the source map.
   Uri _currentUri;
 
-  Program _program;
+  Component _component;
 
   Library _currentLibrary;
 
@@ -200,13 +200,13 @@
 
   final NullableInference _nullableInference;
 
-  factory ProgramCompiler(Program program,
+  factory ProgramCompiler(Component component,
       {bool emitMetadata: true,
       bool replCompile: false,
       Map<String, String> declaredVariables: const {}}) {
-    var nativeTypes = new NativeTypeSet(program);
+    var nativeTypes = new NativeTypeSet(component);
     var types = new TypeSchemaEnvironment(
-        nativeTypes.coreTypes, new ClassHierarchy(program), true);
+        nativeTypes.coreTypes, new ClassHierarchy(component), true);
     return new ProgramCompiler._(
         nativeTypes, new JSTypeRep(types, nativeTypes.sdk),
         emitMetadata: emitMetadata,
@@ -246,11 +246,11 @@
   ClassHierarchy get hierarchy => types.hierarchy;
 
   JS.Program emitProgram(
-      Program p, List<Program> summaries, List<Uri> summaryUris) {
+      Component p, List<Component> summaries, List<Uri> summaryUris) {
     if (_moduleItems.isNotEmpty) {
       throw new StateError('Can only call emitModule once.');
     }
-    _program = p;
+    _component = p;
 
     for (var i = 0; i < summaries.length; i++) {
       var summary = summaries[i];
@@ -3185,7 +3185,7 @@
     if (offset == -1) return null;
     var fileUri = _currentUri;
     if (fileUri == null) return null;
-    var loc = _program.getLocation(fileUri, offset);
+    var loc = _component.getLocation(fileUri, offset);
     if (loc == null) return null;
     return new SourceLocation(offset,
         sourceUrl: fileUri, line: loc.line - 1, column: loc.column - 1);
@@ -3227,6 +3227,13 @@
   visitEmptyStatement(EmptyStatement node) => new JS.EmptyStatement();
 
   @override
+  visitAssertBlock(AssertBlock node) {
+    // AssertBlocks are introduced by the VM-specific async elimination
+    // transformation.  We do not expect them to arise here.
+    throw new UnsupportedError('compilation of an assert block');
+  }
+
+  @override
   visitAssertStatement(AssertStatement node) {
     // TODO(jmesserly): only emit in checked mode.
     var condition = node.condition;
diff --git a/pkg/dev_compiler/lib/src/kernel/native_types.dart b/pkg/dev_compiler/lib/src/kernel/native_types.dart
index deaff11..e862eb9 100644
--- a/pkg/dev_compiler/lib/src/kernel/native_types.dart
+++ b/pkg/dev_compiler/lib/src/kernel/native_types.dart
@@ -36,9 +36,9 @@
   final _nativeTypes = new HashSet<Class>.identity();
   final _pendingLibraries = new HashSet<Library>.identity();
 
-  NativeTypeSet(Program program)
-      : sdk = new LibraryIndex.coreLibraries(program),
-        coreTypes = new CoreTypes(program) {
+  NativeTypeSet(Component component)
+      : sdk = new LibraryIndex.coreLibraries(component),
+        coreTypes = new CoreTypes(component) {
     // First, core types:
     // TODO(vsm): If we're analyzing against the main SDK, those
     // types are not explicitly annotated.
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index cb4f95b..1e1277a 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -63,7 +63,7 @@
       {void logger(String msg)}) {}
 
   @override
-  void performGlobalTransformations(CoreTypes coreTypes, Program program,
+  void performGlobalTransformations(CoreTypes coreTypes, Component component,
       {void logger(String msg)}) {}
 
   @override
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index 3d9348e..742508b 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -465,9 +465,9 @@
 /// to be produced in the set of expressions that cannot be null by DDC's null
 /// inference.
 Future expectNotNull(String code, String expectedNotNull) async {
-  var program = await kernelCompile(code);
+  var component = await kernelCompile(code);
   var collector = new NotNullCollector();
-  program.accept(collector);
+  component.accept(collector);
   var actualNotNull =
       collector.notNullExpressions.map((e) => e.toString()).join(', ');
   expect(actualNotNull, equals(expectedNotNull));
@@ -485,7 +485,7 @@
   int _functionNesting = 0;
 
   @override
-  visitProgram(Program node) {
+  visitComponent(Component node) {
     inference ??= new NullableInference(new JSTypeRep(
         new TypeSchemaEnvironment(
             new CoreTypes(node), new ClassHierarchy(node), true),
@@ -495,7 +495,7 @@
       inference.allowNotNullDeclarations = useAnnotations;
       inference.allowPackageMetaAnnotations = useAnnotations;
     }
-    super.visitProgram(node);
+    super.visitComponent(node);
   }
 
   @override
@@ -542,7 +542,7 @@
 fe.InitializedCompilerState _compilerState;
 final _fileSystem = new MemoryFileSystem(new Uri.file('/memory/'));
 
-Future<Program> kernelCompile(String code) async {
+Future<Component> kernelCompile(String code) async {
   var succeeded = true;
   void errorHandler(fe.CompilationMessage error) {
     if (error.severity == fe.Severity.error) {
@@ -577,5 +577,5 @@
   fe.DdcResult result =
       await fe.compile(_compilerState, [mainUri], errorHandler);
   expect(succeeded, true);
-  return result.program;
+  return result.component;
 }
diff --git a/pkg/dev_compiler/tool/kernel_sdk.dart b/pkg/dev_compiler/tool/kernel_sdk.dart
index b94a9bb..4e8a20b 100755
--- a/pkg/dev_compiler/tool/kernel_sdk.dart
+++ b/pkg/dev_compiler/tool/kernel_sdk.dart
@@ -39,13 +39,13 @@
     ..target = target;
 
   var inputs = target.extraRequiredLibraries.map(Uri.parse).toList();
-  var program = await kernelForBuildUnit(inputs, options);
+  var component = await kernelForComponent(inputs, options);
 
   var outputDir = path.dirname(outputPath);
   await new Directory(outputDir).create(recursive: true);
-  await writeProgramToBinary(program, outputPath);
+  await writeComponentToBinary(component, outputPath);
 
-  var jsModule = compileToJSModule(program, [], [], {});
+  var jsModule = compileToJSModule(component, [], [], {});
   var moduleFormats = {
     'amd': ModuleFormat.amd,
     'common': ModuleFormat.common,
diff --git a/pkg/dev_compiler/web/index.html b/pkg/dev_compiler/web/index.html
index 1ef26e1..891bd19 100644
--- a/pkg/dev_compiler/web/index.html
+++ b/pkg/dev_compiler/web/index.html
@@ -1,12 +1,10 @@
 <!DOCTYPE html>
-
 <html>
   <head>
     <meta charset="utf-8">
-    <title>Dart Browser</title>
+    <title>Dart Dev Compiler Console</title>
   </head>
   <body>
-    <script type="application/dart" src="main.dart"></script>
-    <script src="packages/browser/dart.js"></script>
+    <script defer src="main.dart.js"></script>
   </body>
 </html>
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index ccfe2ea..4710a15 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -83,7 +83,7 @@
   /// of [inputSummaries] or [sdkSummary].
   List<Uri> inputSummaries = [];
 
-  /// URIs of other kernel programs to link.
+  /// URIs of other kernel components to link.
   ///
   /// Commonly used to link the code for the SDK libraries that was compiled
   /// separately. For example, dart2js needs to link the SDK so it can
@@ -91,8 +91,8 @@
   /// always embeds the SDK internally and doesn't need it as part of the
   /// program.
   ///
-  /// The programs provided here should be closed and acyclic: any libraries
-  /// that they reference should be defined in a program in [linkedDependencies]
+  /// The components provided here should be closed and acyclic: any libraries
+  /// that they reference should be defined in a component in [linkedDependencies]
   /// or any of the [inputSummaries] or [sdkSummary].
   List<Uri> linkedDependencies = [];
 
@@ -125,7 +125,7 @@
 
   /// Whether to generate code for the SDK.
   ///
-  /// By default the front end resolves programs using a prebuilt SDK summary.
+  /// By default the front end resolves components using a prebuilt SDK summary.
   /// When this option is `true`, [sdkSummary] must be null.
   bool compileSdk = false;
 
@@ -134,7 +134,7 @@
   ///
   /// This option has different defaults depending on the API.
   ///
-  /// For modular APIs like `kernelForBuildUnit` and `summaryFor` the default
+  /// For modular APIs like `kernelForComponent` and `summaryFor` the default
   /// behavior is `false`. These APIs want to ensure that builds are hermetic,
   /// where all files that will be compiled are listed explicitly and all other
   /// dependencies are covered by summary files.
@@ -169,7 +169,7 @@
   ///   * the set of libraries are part of a platform's SDK (e.g. dart:html for
   ///     dart2js, dart:ui for flutter).
   ///
-  ///   * what kernel transformations should be applied to the program
+  ///   * what kernel transformations should be applied to the component
   ///     (async/await, mixin inlining, etc).
   ///
   ///   * how to deal with non-standard features like `native` extensions.
@@ -185,14 +185,14 @@
   // verbose data (Issue #30056)
   bool verbose = false;
 
-  /// Whether to run extra verification steps to validate that compiled programs
+  /// Whether to run extra verification steps to validate that compiled components
   /// are well formed.
   ///
   /// Errors are reported via the [onError] callback.
   // TODO(sigmund): ensure we don't print errors to stdout (Issue #30056)
   bool verify = false;
 
-  /// Whether to dump generated programs in a text format (also mainly for
+  /// Whether to dump generated components in a text format (also mainly for
   /// debugging).
   ///
   /// Dumped data is printed in stdout.
@@ -202,9 +202,9 @@
   /// warning, etc.) is encountered during compilation.
   bool setExitCodeOnProblem = false;
 
-  /// Whether to embed the input sources in generated kernel programs.
+  /// Whether to embed the input sources in generated kernel components.
   ///
-  /// The kernel `Program` API includes a `uriToSource` map field that is used
+  /// The kernel `Component` API includes a `uriToSource` map field that is used
   /// to embed the entire contents of the source files. This part of the kernel
   /// API is in flux and it is not necessary for some tools. Today it is used
   /// for translating error locations and stack traces in the VM.
diff --git a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
index aac0185..460e203 100644
--- a/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/incremental_kernel_generator.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async' show Future;
 
-import 'package:kernel/kernel.dart' show Program;
+import 'package:kernel/kernel.dart' show Component;
 
 import '../base/processed_options.dart' show ProcessedOptions;
 
@@ -22,9 +22,8 @@
         bootstrapDill);
   }
 
-  /// Returns a component (nee program) whose libraries are the recompiled
-  /// libraries.
-  Future<Program> computeDelta({Uri entryPoint});
+  /// Returns a component whose libraries are the recompiled libraries.
+  Future<Component> computeDelta({Uri entryPoint});
 
   /// Remove the file associated with the given file [uri] from the set of
   /// valid files.  This guarantees that those files will be re-read on the
diff --git a/pkg/front_end/lib/src/api_prototype/kernel_generator.dart b/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
index ddf30e1..94a6d0f 100644
--- a/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/kernel_generator.dart
@@ -7,7 +7,7 @@
 
 import 'dart:async' show Future;
 
-import 'package:kernel/kernel.dart' show Program;
+import 'package:kernel/kernel.dart' show Component;
 
 import '../base/processed_options.dart' show ProcessedOptions;
 
@@ -25,13 +25,13 @@
 /// Generates a kernel representation of the program whose main library is in
 /// the given [source].
 ///
-/// Intended for whole program (non-modular) compilation.
+/// Intended for whole-program (non-modular) compilation.
 ///
 /// Given the Uri of a file containing a program's `main` method, this function
 /// follows `import`, `export`, and `part` declarations to discover the whole
 /// program, and converts the result to Dart Kernel format.
 ///
-/// If `compileSdk` in [options] is true, the generated program will include
+/// If `compileSdk` in [options] is true, the generated component will include
 /// code for the SDK.
 ///
 /// If summaries are provided in [options], the compiler will use them instead
@@ -42,19 +42,19 @@
 /// The input [source] is expected to be a script with a main method, otherwise
 /// an error is reported.
 // TODO(sigmund): rename to kernelForScript?
-Future<Program> kernelForProgram(Uri source, CompilerOptions options) async {
+Future<Component> kernelForProgram(Uri source, CompilerOptions options) async {
   var pOptions = new ProcessedOptions(options, false, [source]);
   return await CompilerContext.runWithOptions(pOptions, (context) async {
-    var program = (await generateKernelInternal())?.program;
-    if (program == null) return null;
+    var component = (await generateKernelInternal())?.component;
+    if (component == null) return null;
 
-    if (program.mainMethod == null) {
+    if (component.mainMethod == null) {
       context.options.report(
           messageMissingMain.withLocation(source, -1, noLength),
           Severity.error);
       return null;
     }
-    return program;
+    return component;
   });
 }
 
@@ -84,11 +84,11 @@
 /// are also listed in the build unit sources, otherwise an error results.  (It
 /// is not permitted to refer to a part file declared in another build unit).
 ///
-/// The return value is a [Program] object with no main method set. The
-/// [Program] includes external libraries for those libraries loaded through
+/// The return value is a [Component] object with no main method set. The
+/// [Component] includes external libraries for those libraries loaded through
 /// summaries.
-Future<Program> kernelForBuildUnit(
+Future<Component> kernelForComponent(
     List<Uri> sources, CompilerOptions options) async {
   return (await generateKernel(new ProcessedOptions(options, true, sources)))
-      ?.program;
+      ?.component;
 }
diff --git a/pkg/front_end/lib/src/api_prototype/summary_generator.dart b/pkg/front_end/lib/src/api_prototype/summary_generator.dart
index 8bd633a..4a2974c 100644
--- a/pkg/front_end/lib/src/api_prototype/summary_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/summary_generator.dart
@@ -43,6 +43,6 @@
 Future<List<int>> summaryFor(List<Uri> sources, CompilerOptions options,
     {bool truncate: false}) async {
   return (await generateKernel(new ProcessedOptions(options, true, sources),
-          buildSummary: true, buildProgram: false, truncateSummary: truncate))
+          buildSummary: true, buildComponent: false, truncateSummary: truncate))
       ?.summary;
 }
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index bad1ff9..c8151c0 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -4,7 +4,7 @@
 
 import 'dart:async' show Future;
 
-import 'package:kernel/kernel.dart' show Program;
+import 'package:kernel/kernel.dart' show Component;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -46,7 +46,7 @@
   return new InitializedCompilerState(options, processedOpts);
 }
 
-Future<Program> compile(InitializedCompilerState state, bool verbose,
+Future<Component> compile(InitializedCompilerState state, bool verbose,
     FileSystem fileSystem, ErrorHandler onError, Uri input) async {
   CompilerOptions options = state.options;
   options
@@ -62,9 +62,9 @@
   var compilerResult = await CompilerContext.runWithOptions(processedOpts,
       (CompilerContext context) async {
     var compilerResult = await generateKernelInternal();
-    Program program = compilerResult?.program;
-    if (program == null) return null;
-    if (program.mainMethod == null) {
+    Component component = compilerResult?.component;
+    if (component == null) return null;
+    if (component.mainMethod == null) {
       context.options.report(
           messageMissingMain.withLocation(input, -1, noLength), Severity.error);
       return null;
@@ -72,5 +72,5 @@
     return compilerResult;
   });
 
-  return compilerResult?.program;
+  return compilerResult?.component;
 }
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index 5e0cf2c..0b9545f 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -8,7 +8,7 @@
 import 'package:front_end/src/api_prototype/standard_file_system.dart';
 import 'package:front_end/src/base/processed_options.dart';
 import 'package:front_end/src/kernel_generator_impl.dart';
-import 'package:kernel/kernel.dart' show Program;
+import 'package:kernel/kernel.dart' show Component;
 import 'package:kernel/target/targets.dart' show Target;
 
 import '../api_prototype/compiler_options.dart';
@@ -19,10 +19,10 @@
 export '../api_prototype/compilation_message.dart';
 
 class DdcResult {
-  final Program program;
-  final List<Program> inputSummaries;
+  final Component component;
+  final List<Component> inputSummaries;
 
-  DdcResult(this.program, this.inputSummaries);
+  DdcResult(this.component, this.inputSummaries);
 }
 
 Future<InitializedCompilerState> initializeCompiler(
@@ -85,10 +85,10 @@
 
   var compilerResult = await generateKernel(processedOpts);
 
-  var program = compilerResult?.program;
-  if (program == null) return null;
+  var component = compilerResult?.component;
+  if (component == null) return null;
 
   // This should be cached.
   var summaries = await processedOpts.loadInputSummaries(null);
-  return new DdcResult(program, summaries);
+  return new DdcResult(component, summaries);
 }
diff --git a/pkg/front_end/lib/src/api_unstable/summary_worker.dart b/pkg/front_end/lib/src/api_unstable/summary_worker.dart
index d5c8b18..2144265 100644
--- a/pkg/front_end/lib/src/api_unstable/summary_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/summary_worker.dart
@@ -56,6 +56,6 @@
   processedOpts.inputs.addAll(inputs);
 
   var result = await generateKernel(processedOpts,
-      buildSummary: true, buildProgram: false, truncateSummary: true);
+      buildSummary: true, buildComponent: false, truncateSummary: true);
   return result?.summary;
 }
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 3dc85f7..cbe7ebc 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -6,7 +6,7 @@
 
 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
 
-import 'package:kernel/kernel.dart' show CanonicalName, Location, Program;
+import 'package:kernel/kernel.dart' show CanonicalName, Component, Location;
 
 import 'package:kernel/target/targets.dart' show Target, TargetFlags;
 
@@ -98,23 +98,23 @@
 
   /// The SDK summary, or `null` if it has not been read yet.
   ///
-  /// A summary, also referred to as "outline" internally, is a [Program] where
+  /// A summary, also referred to as "outline" internally, is a [Component] where
   /// all method bodies are left out. In essence, it contains just API
   /// signatures and constants. When strong-mode is enabled, the summary already
   /// includes inferred types.
-  Program _sdkSummaryProgram;
+  Component _sdkSummaryProgram;
 
   /// The summary for each uri in `options.inputSummaries`.
   ///
-  /// A summary, also referred to as "outline" internally, is a [Program] where
+  /// A summary, also referred to as "outline" internally, is a [Component] where
   /// all method bodies are left out. In essence, it contains just API
   /// signatures and constants. When strong-mode is enabled, the summary already
   /// includes inferred types.
-  List<Program> _inputSummariesPrograms;
+  List<Component> _inputSummariesPrograms;
 
   /// Other programs that are meant to be linked and compiled with the input
   /// sources.
-  List<Program> _linkedDependencies;
+  List<Component> _linkedDependencies;
 
   /// The location of the SDK, or `null` if the location hasn't been determined
   /// yet.
@@ -306,18 +306,18 @@
   Target get target => _target ??=
       _raw.target ?? new VmTarget(new TargetFlags(strongMode: strongMode));
 
-  /// Get an outline program that summarizes the SDK, if any.
+  /// Get an outline component that summarizes the SDK, if any.
   // TODO(sigmund): move, this doesn't feel like an "option".
-  Future<Program> loadSdkSummary(CanonicalName nameRoot) async {
+  Future<Component> loadSdkSummary(CanonicalName nameRoot) async {
     if (_sdkSummaryProgram == null) {
       if (sdkSummary == null) return null;
       var bytes = await loadSdkSummaryBytes();
-      _sdkSummaryProgram = loadProgram(bytes, nameRoot);
+      _sdkSummaryProgram = loadComponent(bytes, nameRoot);
     }
     return _sdkSummaryProgram;
   }
 
-  void set sdkSummaryComponent(Program platform) {
+  void set sdkSummaryComponent(Component platform) {
     if (_sdkSummaryProgram != null) {
       throw new StateError("sdkSummary already loaded.");
     }
@@ -327,42 +327,42 @@
   /// Get the summary programs for each of the underlying `inputSummaries`
   /// provided via [CompilerOptions].
   // TODO(sigmund): move, this doesn't feel like an "option".
-  Future<List<Program>> loadInputSummaries(CanonicalName nameRoot) async {
+  Future<List<Component>> loadInputSummaries(CanonicalName nameRoot) async {
     if (_inputSummariesPrograms == null) {
       var uris = _raw.inputSummaries;
-      if (uris == null || uris.isEmpty) return const <Program>[];
+      if (uris == null || uris.isEmpty) return const <Component>[];
       // TODO(sigmund): throttle # of concurrent opreations.
       var allBytes = await Future
           .wait(uris.map((uri) => fileSystem.entityForUri(uri).readAsBytes()));
       _inputSummariesPrograms =
-          allBytes.map((bytes) => loadProgram(bytes, nameRoot)).toList();
+          allBytes.map((bytes) => loadComponent(bytes, nameRoot)).toList();
     }
     return _inputSummariesPrograms;
   }
 
   /// Load each of the [CompilerOptions.linkedDependencies] programs.
   // TODO(sigmund): move, this doesn't feel like an "option".
-  Future<List<Program>> loadLinkDependencies(CanonicalName nameRoot) async {
+  Future<List<Component>> loadLinkDependencies(CanonicalName nameRoot) async {
     if (_linkedDependencies == null) {
       var uris = _raw.linkedDependencies;
-      if (uris == null || uris.isEmpty) return const <Program>[];
+      if (uris == null || uris.isEmpty) return const <Component>[];
       // TODO(sigmund): throttle # of concurrent opreations.
       var allBytes = await Future
           .wait(uris.map((uri) => fileSystem.entityForUri(uri).readAsBytes()));
       _linkedDependencies =
-          allBytes.map((bytes) => loadProgram(bytes, nameRoot)).toList();
+          allBytes.map((bytes) => loadComponent(bytes, nameRoot)).toList();
     }
     return _linkedDependencies;
   }
 
   /// Helper to load a .dill file from [uri] using the existing [nameRoot].
-  Program loadProgram(List<int> bytes, CanonicalName nameRoot) {
-    Program program = new Program(nameRoot: nameRoot);
+  Component loadComponent(List<int> bytes, CanonicalName nameRoot) {
+    Component component = new Component(nameRoot: nameRoot);
     // TODO(ahe): Pass file name to BinaryBuilder.
     // TODO(ahe): Control lazy loading via an option.
     new BinaryBuilder(bytes, filename: null, disableLazyReading: false)
-        .readProgram(program);
-    return program;
+        .readComponent(component);
+    return component;
   }
 
   /// Get the [UriTranslator] which resolves "package:" and "dart:" URIs.
diff --git a/pkg/front_end/lib/src/external_state_snapshot.dart b/pkg/front_end/lib/src/external_state_snapshot.dart
index cdb31e9..0484dc0 100644
--- a/pkg/front_end/lib/src/external_state_snapshot.dart
+++ b/pkg/front_end/lib/src/external_state_snapshot.dart
@@ -4,15 +4,15 @@
 
 // TODO(ahe): Remove this file.
 
-import 'package:kernel/kernel.dart' show Library, Program;
+import 'package:kernel/kernel.dart' show Library, Component;
 
 /// Helper class to work around modifications in [kernel_generator_impl.dart].
 class ExternalStateSnapshot {
   final List<ExternalState> snapshots;
 
-  ExternalStateSnapshot(Program program)
+  ExternalStateSnapshot(Component component)
       : snapshots = new List<ExternalState>.from(
-            program.libraries.map((l) => new ExternalState(l, l.isExternal)));
+            component.libraries.map((l) => new ExternalState(l, l.isExternal)));
 
   void restore() {
     for (ExternalState state in snapshots) {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
index 713a5e6..2be3fcf 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async' show Future;
 
-import 'package:kernel/ast.dart' show Library, Program, Source;
+import 'package:kernel/ast.dart' show Library, Component, Source;
 
 import '../fasta_codes.dart'
     show SummaryTemplate, Template, templateDillOutlineSummary;
@@ -33,12 +33,12 @@
   Template<SummaryTemplate> get outlineSummaryTemplate =>
       templateDillOutlineSummary;
 
-  /// Append compiled libraries from the given [program]. If the [filter] is
+  /// Append compiled libraries from the given [component]. If the [filter] is
   /// provided, append only libraries whose [Uri] is accepted by the [filter].
-  List<DillLibraryBuilder> appendLibraries(Program program,
+  List<DillLibraryBuilder> appendLibraries(Component component,
       {bool filter(Uri uri), int byteCount: 0}) {
     var builders = <DillLibraryBuilder>[];
-    for (Library library in program.libraries) {
+    for (Library library in component.libraries) {
       if (filter == null || filter(library.importUri)) {
         libraries.add(library);
         DillLibraryBuilder builder = read(library.importUri, -1);
@@ -46,7 +46,7 @@
         builders.add(builder);
       }
     }
-    uriToSource.addAll(program.uriToSource);
+    uriToSource.addAll(component.uriToSource);
     this.byteCount += byteCount;
     return builders;
   }
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_target.dart b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
index 7da0d21..405f1f8 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_target.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_target.dart
@@ -43,8 +43,8 @@
   }
 
   @override
-  Future<Null> buildProgram() {
-    return new Future<Null>.sync(() => unsupported("buildProgram", -1, null));
+  Future<Null> buildComponent() {
+    return new Future<Null>.sync(() => unsupported("buildComponent", -1, null));
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/get_dependencies.dart b/pkg/front_end/lib/src/fasta/get_dependencies.dart
index b9d7999..14165b7 100644
--- a/pkg/front_end/lib/src/fasta/get_dependencies.dart
+++ b/pkg/front_end/lib/src/fasta/get_dependencies.dart
@@ -6,7 +6,7 @@
 
 import 'dart:async' show Future;
 
-import 'package:kernel/kernel.dart' show loadProgramFromBytes;
+import 'package:kernel/kernel.dart' show loadComponentFromBytes;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -47,7 +47,7 @@
         new DillTarget(c.options.ticker, uriTranslator, c.options.target);
     if (platform != null) {
       var bytes = await fileSystem.entityForUri(platform).readAsBytes();
-      var platformProgram = loadProgramFromBytes(bytes);
+      var platformProgram = loadComponentFromBytes(bytes);
       dillTarget.loader.appendLibraries(platformProgram);
     }
     KernelTarget kernelTarget = new KernelTarget(
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index c530048..eba0a79 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -8,7 +8,7 @@
 
 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
 
-import 'package:kernel/kernel.dart' show Library, Procedure, Program, Source;
+import 'package:kernel/kernel.dart' show Library, Procedure, Component, Source;
 
 import '../api_prototype/incremental_kernel_generator.dart'
     show IncrementalKernelGenerator;
@@ -52,10 +52,10 @@
       : ticker = context.options.ticker;
 
   @override
-  Future<Program> computeDelta({Uri entryPoint}) async {
+  Future<Component> computeDelta({Uri entryPoint}) async {
     ticker.reset();
     entryPoint ??= context.options.inputs.single;
-    return context.runInContext<Future<Program>>((CompilerContext c) async {
+    return context.runInContext<Future<Component>>((CompilerContext c) async {
       IncrementalCompilerData data = new IncrementalCompilerData();
       if (dillLoadedData == null) {
         UriTranslator uriTranslator = await c.options.getUriTranslator();
@@ -67,7 +67,7 @@
           try {
             bytesLength += await initializeFromDill(summaryBytes, c, data);
           } catch (e) {
-            // We might have loaded x out of y libraries into the program.
+            // We might have loaded x out of y libraries into the component.
             // To avoid any unforeseen problems start over.
             bytesLength = prepareSummary(summaryBytes, uriTranslator, c, data);
           }
@@ -131,10 +131,10 @@
 
       await userCode.buildOutlines();
 
-      // This is not the full program. It is the program including all
+      // This is not the full program. It is the component including all
       // libraries loaded from .dill files.
-      Program programWithDill =
-          await userCode.buildProgram(verify: c.options.verify);
+      Component programWithDill =
+          await userCode.buildComponent(verify: c.options.verify);
 
       List<Library> libraries =
           new List<Library>.from(userCode.loader.libraries);
@@ -158,11 +158,12 @@
         });
       }
 
-      // This is the incremental program.
+      // This component represents the parts of the program that were
+      // recompiled.
       Procedure mainMethod = programWithDill == null
           ? data.userLoadedUriMain
           : programWithDill.mainMethod;
-      return new Program(libraries: libraries, uriToSource: data.uriToSource)
+      return new Component(libraries: libraries, uriToSource: data.uriToSource)
         ..mainMethod = mainMethod;
     });
   }
@@ -174,9 +175,9 @@
 
     if (summaryBytes != null) {
       ticker.logMs("Read ${c.options.sdkSummary}");
-      data.program = new Program();
+      data.component = new Component();
       new BinaryBuilder(summaryBytes, disableLazyReading: false)
-          .readProgram(data.program);
+          .readComponent(data.component);
       ticker.logMs("Deserialized ${c.options.sdkSummary}");
       bytesLength += summaryBytes.length;
     }
@@ -194,32 +195,32 @@
       List<int> initializationBytes = await entity.readAsBytes();
       if (initializationBytes != null) {
         Set<Uri> prevLibraryUris = new Set<Uri>.from(
-            data.program.libraries.map((Library lib) => lib.importUri));
+            data.component.libraries.map((Library lib) => lib.importUri));
         ticker.logMs("Read $initializeFromDillUri");
 
         // We're going to output all we read here so lazy loading it
         // doesn't make sense.
         new BinaryBuilder(initializationBytes, disableLazyReading: true)
-            .readProgram(data.program);
+            .readComponent(data.component);
 
         initializedFromDill = true;
         bytesLength += initializationBytes.length;
-        for (Library lib in data.program.libraries) {
+        for (Library lib in data.component.libraries) {
           if (prevLibraryUris.contains(lib.importUri)) continue;
           data.importUriToOrder[lib.importUri] = data.importUriToOrder.length;
         }
-        data.userLoadedUriMain = data.program.mainMethod;
+        data.userLoadedUriMain = data.component.mainMethod;
         data.includeUserLoadedLibraries = true;
-        data.uriToSource.addAll(data.program.uriToSource);
+        data.uriToSource.addAll(data.component.uriToSource);
       }
     }
     return bytesLength;
   }
 
   void appendLibraries(IncrementalCompilerData data, int bytesLength) {
-    if (data.program != null) {
+    if (data.component != null) {
       dillLoadedData.loader
-          .appendLibraries(data.program, byteCount: bytesLength);
+          .appendLibraries(data.component, byteCount: bytesLength);
     }
     ticker.logMs("Appended libraries");
   }
@@ -327,7 +328,7 @@
   Map<Uri, Source> uriToSource;
   Map<Uri, int> importUriToOrder;
   Procedure userLoadedUriMain;
-  Program program;
+  Component component;
 
   IncrementalCompilerData() {
     reset();
@@ -338,6 +339,6 @@
     uriToSource = <Uri, Source>{};
     importUriToOrder = <Uri, int>{};
     userLoadedUriMain = null;
-    program = null;
+    component = null;
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_outline_shaker.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_outline_shaker.dart
index 979fc5f..687e5ff 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_outline_shaker.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_outline_shaker.dart
@@ -17,11 +17,11 @@
 /// the included libraries. Only outlines are serialized, even for included
 /// libraries, all function bodies are ignored.
 void serializeTrimmedOutline(
-    Sink<List<int>> sink, Program program, bool isIncluded(Uri uri)) {
+    Sink<List<int>> sink, Component component, bool isIncluded(Uri uri)) {
   var data = new _RetainedDataBuilder();
-  data._markRequired(program);
+  data._markRequired(component);
 
-  for (var library in program.libraries) {
+  for (var library in component.libraries) {
     if (!isIncluded(library.importUri)) continue;
     data.markAdditionalExports(library);
     for (var clazz in library.classes) {
@@ -42,35 +42,36 @@
     }
   }
 
-  new _TrimmedBinaryPrinter(sink, isIncluded, data).writeProgramFile(program);
+  new _TrimmedBinaryPrinter(sink, isIncluded, data)
+      .writeComponentFile(component);
 }
 
-/// Removes unnecessary libraries, classes, and members from [program].
+/// Removes unnecessary libraries, classes, and members from [component].
 ///
 /// This applies a simple "tree-shaking" technique: the full body of libraries
 /// whose URI match [isIncluded] is preserved, and so is the outline of the
 /// members and classes which are transitively visible from the
 /// included libraries.
 ///
-/// The intent is that the resulting program has the entire code that is meant
+/// The intent is that the resulting component has the entire code that is meant
 /// to be included and the minimum required to prevent dangling references and
 /// allow modular program transformations.
 ///
-/// Note that the resulting program may include libraries not in [isIncluded],
+/// Note that the resulting component may include libraries not in [isIncluded],
 /// but those will be marked as external. There should be no method bodies for
 /// any members of those libraries.
-void trimProgram(Program program, bool isIncluded(Uri uri)) {
+void trimProgram(Component component, bool isIncluded(Uri uri)) {
   var data = new _RetainedDataBuilder();
-  data._markRequired(program);
+  data._markRequired(component);
 
-  data.markMember(program.mainMethod);
-  for (var library in program.libraries) {
+  data.markMember(component.mainMethod);
+  for (var library in component.libraries) {
     if (isIncluded(library.importUri)) {
       library.accept(data);
     }
   }
 
-  new _KernelOutlineShaker(isIncluded, data).transform(program);
+  new _KernelOutlineShaker(isIncluded, data).transform(component);
 }
 
 /// Transformer that trims everything in the excluded libraries that is not
@@ -109,9 +110,9 @@
   @override
   TreeNode defaultTreeNode(TreeNode node) => node;
 
-  void transform(Program program) {
+  void transform(Component component) {
     var toRemove = new Set<Library>();
-    for (var library in program.libraries) {
+    for (var library in component.libraries) {
       if (!isIncluded(library.importUri)) {
         if (!data.isLibraryUsed(library)) {
           toRemove.add(library);
@@ -121,7 +122,7 @@
         }
       }
     }
-    program.libraries.removeWhere(toRemove.contains);
+    component.libraries.removeWhere(toRemove.contains);
   }
 
   @override
@@ -530,8 +531,8 @@
   /// transformers.
   // TODO(sigmund): consider being more fine-grained and only marking what is
   // seen and used.
-  void _markRequired(Program program) {
-    var coreTypes = new CoreTypes(program);
+  void _markRequired(Component component) {
+    var coreTypes = new CoreTypes(component);
     coreTypes.objectClass.members.forEach(markMember);
 
     // These are assumed to be available by fasta:
@@ -660,8 +661,8 @@
   }
 
   @override
-  void writeLibraries(Program program) {
-    for (var library in program.libraries) {
+  void writeLibraries(Component component) {
+    for (var library in component.libraries) {
       if (isIncluded(library.importUri) || data.isLibraryUsed(library)) {
         librariesToWrite.add(library);
       }
@@ -697,8 +698,8 @@
   }
 
   @override
-  void writeProgramIndex(Program program, List<Library> libraries) {
-    super.writeProgramIndex(program, librariesToWrite);
+  void writeComponentIndex(Component component, List<Library> libraries) {
+    super.writeComponentIndex(component, librariesToWrite);
   }
 
   @override
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 388fd98..9550057 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -30,7 +30,7 @@
         NullLiteral,
         Procedure,
         ProcedureKind,
-        Program,
+        Component,
         Source,
         Statement,
         StringLiteral,
@@ -92,7 +92,7 @@
 
 import 'metadata_collector.dart' show MetadataCollector;
 
-import 'verifier.dart' show verifyProgram;
+import 'verifier.dart' show verifyComponent;
 
 class KernelTarget extends TargetImplementation {
   /// The [FileSystem] which should be used to access files.
@@ -111,7 +111,7 @@
 
   SourceLoader<Library> loader;
 
-  Program program;
+  Component component;
 
   final List<LocatedMessage> errors = <LocatedMessage>[];
 
@@ -220,17 +220,17 @@
     builder.mixedInType = null;
   }
 
-  void handleInputError(deprecated_InputError error, {bool isFullProgram}) {
+  void handleInputError(deprecated_InputError error, {bool isFullComponent}) {
     if (error != null) {
       LocatedMessage message = deprecated_InputError.toMessage(error);
       context.report(message, Severity.error);
       errors.add(message);
     }
-    program = erroneousProgram(isFullProgram);
+    component = erroneousComponent(isFullComponent);
   }
 
   @override
-  Future<Program> buildOutlines({CanonicalName nameRoot}) async {
+  Future<Component> buildOutlines({CanonicalName nameRoot}) async {
     if (loader.first == null) return null;
     try {
       loader.createTypeInferenceEngine();
@@ -248,14 +248,14 @@
       List<SourceClassBuilder> myClasses = collectMyClasses();
       loader.checkSemantics(myClasses);
       loader.finishTypeVariables(objectClassBuilder);
-      loader.buildProgram();
+      loader.buildComponent();
       installDefaultSupertypes();
       installDefaultConstructors(myClasses);
       loader.resolveConstructors();
-      program =
+      component =
           link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
       if (metadataCollector != null) {
-        program.addMetadataRepository(metadataCollector.repository);
+        component.addMetadataRepository(metadataCollector.repository);
       }
       computeCoreTypes();
       loader.computeHierarchy();
@@ -266,30 +266,30 @@
       loader.checkOverrides(myClasses);
     } on deprecated_InputError catch (e) {
       ticker.logMs("Got deprecated_InputError");
-      handleInputError(e, isFullProgram: false);
+      handleInputError(e, isFullComponent: false);
     } catch (e, s) {
       return reportCrash(e, s, loader?.currentUriForCrashReporting);
     }
-    return program;
+    return component;
   }
 
-  /// Build the kernel representation of the program loaded by this target. The
-  /// program will contain full bodies for the code loaded from sources, and
+  /// Build the kernel representation of the component loaded by this target. The
+  /// component will contain full bodies for the code loaded from sources, and
   /// only references to the code loaded by the [DillTarget], which may or may
   /// not include method bodies (depending on what was loaded into that target,
-  /// an outline or a full kernel program).
+  /// an outline or a full kernel component).
   ///
-  /// If [verify], run the default kernel verification on the resulting program.
+  /// If [verify], run the default kernel verification on the resulting component.
   @override
-  Future<Program> buildProgram({bool verify: false}) async {
+  Future<Component> buildComponent({bool verify: false}) async {
     if (loader.first == null) return null;
     if (errors.isNotEmpty) {
-      handleInputError(null, isFullProgram: true);
-      return program;
+      handleInputError(null, isFullComponent: true);
+      return component;
     }
 
     try {
-      ticker.logMs("Building program");
+      ticker.logMs("Building component");
       await loader.buildBodies();
       loader.finishDeferredLoadTearoffs();
       List<SourceClassBuilder> myClasses = collectMyClasses();
@@ -300,16 +300,16 @@
 
       if (verify) this.verify();
       if (errors.isNotEmpty) {
-        handleInputError(null, isFullProgram: true);
+        handleInputError(null, isFullComponent: true);
       }
       handleRecoverableErrors(loader.unhandledErrors);
     } on deprecated_InputError catch (e) {
       ticker.logMs("Got deprecated_InputError");
-      handleInputError(e, isFullProgram: true);
+      handleInputError(e, isFullComponent: true);
     } catch (e, s) {
       return reportCrash(e, s, loader?.currentUriForCrashReporting);
     }
-    return program;
+    return component;
   }
 
   /// Adds a synthetic field named `#errors` to the main library that contains
@@ -317,13 +317,13 @@
   ///
   /// If [recoverableErrors] is empty, this method does nothing.
   ///
-  /// If there's no main library, this method uses [erroneousProgram] to
-  /// replace [program].
+  /// If there's no main library, this method uses [erroneousComponent] to
+  /// replace [component].
   void handleRecoverableErrors(List<LocatedMessage> recoverableErrors) {
     if (recoverableErrors.isEmpty) return;
     KernelLibraryBuilder mainLibrary = loader.first;
     if (mainLibrary == null) {
-      program = erroneousProgram(true);
+      component = erroneousComponent(true);
       return;
     }
     List<Expression> expressions = <Expression>[];
@@ -337,13 +337,13 @@
         isStatic: true));
   }
 
-  Program erroneousProgram(bool isFullProgram) {
+  Component erroneousComponent(bool isFullComponent) {
     Uri uri = loader.first?.uri ?? Uri.parse("error:error");
     Uri fileUri = loader.first?.fileUri ?? uri;
     KernelLibraryBuilder library =
         new KernelLibraryBuilder(uri, fileUri, loader, null);
     loader.first = library;
-    if (isFullProgram) {
+    if (isFullComponent) {
       // If this is an outline, we shouldn't add an executable main
       // method. Similarly considerations apply to separate compilation. It
       // could also make sense to add a way to mark .dill files as having
@@ -360,9 +360,9 @@
     return link(<Library>[library.library]);
   }
 
-  /// Creates a program by combining [libraries] with the libraries of
-  /// `dillTarget.loader.program`.
-  Program link(List<Library> libraries, {CanonicalName nameRoot}) {
+  /// Creates a component by combining [libraries] with the libraries of
+  /// `dillTarget.loader.component`.
+  Component link(List<Library> libraries, {CanonicalName nameRoot}) {
     libraries.addAll(dillTarget.loader.libraries);
 
     Map<Uri, Source> uriToSource = new Map<Uri, Source>();
@@ -374,22 +374,22 @@
     this.uriToSource.forEach(copySource);
     dillTarget.loader.uriToSource.forEach(copySource);
 
-    Program program = new Program(
+    Component component = new Component(
         nameRoot: nameRoot, libraries: libraries, uriToSource: uriToSource);
     if (loader.first != null) {
       // TODO(sigmund): do only for full program
       Builder builder = loader.first.exportScope.lookup("main", -1, null);
       if (builder is KernelProcedureBuilder) {
-        program.mainMethod = builder.procedure;
+        component.mainMethod = builder.procedure;
       } else if (builder is DillMemberBuilder) {
         if (builder.member is Procedure) {
-          program.mainMethod = builder.member;
+          component.mainMethod = builder.member;
         }
       }
     }
 
-    ticker.logMs("Linked program");
-    return program;
+    ticker.logMs("Linked component");
+    return component;
   }
 
   void installDefaultSupertypes() {
@@ -575,7 +575,7 @@
         libraries.add(library.target);
       }
     }
-    Program plaformLibraries = new Program();
+    Component plaformLibraries = new Component();
     // Add libraries directly to prevent that their parents are changed.
     plaformLibraries.libraries.addAll(libraries);
     loader.computeCoreTypes(plaformLibraries);
@@ -711,8 +711,8 @@
   }
 
   void verify() {
-    errors.addAll(verifyProgram(program));
-    ticker.logMs("Verified program");
+    errors.addAll(verifyComponent(component));
+    ticker.logMs("Verified component");
   }
 
   /// Return `true` if the given [library] was built by this [KernelTarget]
diff --git a/pkg/front_end/lib/src/fasta/kernel/metadata_collector.dart b/pkg/front_end/lib/src/fasta/kernel/metadata_collector.dart
index 944540a..2b73d92 100644
--- a/pkg/front_end/lib/src/fasta/kernel/metadata_collector.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/metadata_collector.dart
@@ -7,7 +7,7 @@
 /// The collector to add target specific metadata to.
 abstract class MetadataCollector {
   /// Metadata is remembered in this repository, so that when it is added
-  /// to a program, metadata is serialized with the program.
+  /// to a component, metadata is serialized with the component.
   MetadataRepository get repository;
 
   void setConstructorNameOffset(Member node, Object name);
diff --git a/pkg/front_end/lib/src/fasta/kernel/utils.dart b/pkg/front_end/lib/src/fasta/kernel/utils.dart
index 4a9bd7f0..8bcda60 100644
--- a/pkg/front_end/lib/src/fasta/kernel/utils.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/utils.dart
@@ -6,7 +6,7 @@
 
 import 'dart:io' show BytesBuilder, File, IOSink;
 
-import 'package:kernel/ast.dart' show Library, Program;
+import 'package:kernel/ast.dart' show Library, Component;
 
 import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
 
@@ -15,13 +15,14 @@
 
 import 'package:kernel/text/ast_to_text.dart' show Printer;
 
-/// Print the given [program].  Do nothing if it is `null`.  If the
+/// Print the given [component].  Do nothing if it is `null`.  If the
 /// [libraryFilter] is provided, then only libraries that satisfy it are
 /// printed.
-void printProgramText(Program program, {bool libraryFilter(Library library)}) {
-  if (program == null) return;
+void printComponentText(Component component,
+    {bool libraryFilter(Library library)}) {
+  if (component == null) return;
   StringBuffer sb = new StringBuffer();
-  for (Library library in program.libraries) {
+  for (Library library in component.libraries) {
     if (libraryFilter != null && !libraryFilter(library)) continue;
     Printer printer = new Printer(sb);
     printer.writeLibraryFile(library);
@@ -29,8 +30,8 @@
   print(sb);
 }
 
-/// Write [program] to file only including libraries that match [filter].
-Future<Null> writeProgramToFile(Program program, Uri uri,
+/// Write [component] to file only including libraries that match [filter].
+Future<Null> writeComponentToFile(Component component, Uri uri,
     {bool filter(Library library)}) async {
   File output = new File.fromUri(uri);
   IOSink sink = output.openWrite();
@@ -38,22 +39,22 @@
     BinaryPrinter printer = filter == null
         ? new BinaryPrinter(sink)
         : new LimitedBinaryPrinter(sink, filter ?? (_) => true, false);
-    printer.writeProgramFile(program);
-    program.unbindCanonicalNames();
+    printer.writeComponentFile(component);
+    component.unbindCanonicalNames();
   } finally {
     await sink.close();
   }
 }
 
-/// Serialize the libraries in [program] that match [filter].
-List<int> serializeProgram(Program program,
+/// Serialize the libraries in [component] that match [filter].
+List<int> serializeComponent(Component component,
     {bool filter(Library library), bool excludeUriToSource: false}) {
   ByteSink byteSink = new ByteSink();
   BinaryPrinter printer = filter == null && !excludeUriToSource
       ? new BinaryPrinter(byteSink)
       : new LimitedBinaryPrinter(
           byteSink, filter ?? (_) => true, excludeUriToSource);
-  printer.writeProgramFile(program);
+  printer.writeComponentFile(component);
   return byteSink.builder.takeBytes();
 }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/verifier.dart b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
index 6cfa12c..86aaafd 100644
--- a/pkg/front_end/lib/src/fasta/kernel/verifier.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
@@ -14,7 +14,7 @@
         Library,
         Member,
         Procedure,
-        Program,
+        Component,
         StaticInvocation,
         SuperMethodInvocation,
         SuperPropertyGet,
@@ -37,9 +37,11 @@
 import 'redirecting_factory_body.dart'
     show RedirectingFactoryBody, getRedirectingFactoryBody;
 
-List<LocatedMessage> verifyProgram(Program program, {bool isOutline: false}) {
-  FastaVerifyingVisitor verifier = new FastaVerifyingVisitor(isOutline);
-  program.accept(verifier);
+List<LocatedMessage> verifyComponent(Component component,
+    {bool isOutline: false, bool skipPlatform: false}) {
+  FastaVerifyingVisitor verifier =
+      new FastaVerifyingVisitor(isOutline, skipPlatform);
+  component.accept(verifier);
   return verifier.errors;
 }
 
@@ -48,8 +50,9 @@
   final List<LocatedMessage> errors = <LocatedMessage>[];
 
   Uri fileUri;
+  final bool skipPlatform;
 
-  FastaVerifyingVisitor(bool isOutline) {
+  FastaVerifyingVisitor(bool isOutline, this.skipPlatform) {
     this.isOutline = isOutline;
   }
 
@@ -129,6 +132,10 @@
 
   @override
   visitLibrary(Library node) {
+    // Issue(http://dartbug.com/32530)
+    if (skipPlatform && node.importUri.scheme == 'dart') {
+      return;
+    }
     fileUri = checkLocation(node, node.name, node.fileUri);
     super.visitLibrary(node);
   }
diff --git a/pkg/front_end/lib/src/fasta/messages.dart b/pkg/front_end/lib/src/fasta/messages.dart
index 9c654de..397ce96 100644
--- a/pkg/front_end/lib/src/fasta/messages.dart
+++ b/pkg/front_end/lib/src/fasta/messages.dart
@@ -4,7 +4,7 @@
 
 library fasta.messages;
 
-import 'package:kernel/ast.dart' show Library, Location, Program, TreeNode;
+import 'package:kernel/ast.dart' show Library, Location, Component, TreeNode;
 
 import 'compiler_context.dart' show CompilerContext;
 
@@ -28,18 +28,18 @@
 }
 
 Location getLocationFromNode(TreeNode node) {
-  if (node.enclosingProgram == null) {
+  if (node.enclosingComponent == null) {
     TreeNode parent = node;
     while (parent != null && parent is! Library) {
       parent = parent.parent;
     }
     if (parent is Library) {
-      Program program =
-          new Program(uriToSource: CompilerContext.current.uriToSource);
-      program.libraries.add(parent);
-      parent.parent = program;
+      Component component =
+          new Component(uriToSource: CompilerContext.current.uriToSource);
+      component.libraries.add(parent);
+      parent.parent = component;
       Location result = node.location;
-      program.libraries.clear();
+      component.libraries.clear();
       parent.parent = null;
       return result;
     } else {
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 466f059..5203691 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -93,7 +93,13 @@
 import 'type_continuation.dart'
     show TypeContinuation, typeContinuationFromFormalParameterKind;
 
-import 'type_info.dart' show isGeneralizedFunctionType, isValidTypeReference;
+import 'type_info.dart'
+    show
+        TypeInfo,
+        computeType,
+        isGeneralizedFunctionType,
+        isValidTypeReference,
+        noTypeInfo;
 
 import 'util.dart' show closeBraceTokenFor, optional;
 
@@ -5508,13 +5514,92 @@
     return token;
   }
 
-  Token parseVariablesDeclaration(Token token) {
-    token = parseMetadataStar(token);
-    return parseVariablesDeclarationMaybeSemicolon(token, true);
+  /// Parse the metadata, modifiers, and type of a local declaration and return
+  /// the last token consumed. If a local variable declaration or local
+  /// function declaration is not found, then return the starting token.
+  Token parseLocalDeclarationStartOpt(final Token start) {
+    Token token = start;
+    Token next = token.next;
+    if (optional('@', next)) {
+      token = parseMetadataStar(token);
+      next = token.next;
+    }
+
+    TypeContinuation typeContinuation;
+    Token varFinalOrConst;
+    if (isModifier(next)) {
+      if (optional('var', next)) {
+        typeContinuation = TypeContinuation.OptionalAfterVar;
+        varFinalOrConst = token = token.next;
+        next = token.next;
+      } else if (optional('final', next) || optional('const', next)) {
+        typeContinuation = TypeContinuation.Optional;
+        varFinalOrConst = token = token.next;
+        next = token.next;
+      }
+
+      if (isModifier(next)) {
+        // Recovery
+        ModifierRecoveryContext2 modifierContext =
+            new ModifierRecoveryContext2(this);
+        token = modifierContext.parseVariableDeclarationModifiers(
+            token, typeContinuation,
+            varFinalOrConst: varFinalOrConst);
+        next = token.next;
+
+        varFinalOrConst = modifierContext.varFinalOrConst;
+        typeContinuation = modifierContext.typeContinuation;
+        modifierContext = null;
+      }
+    }
+
+    Token beforeType = token;
+    TypeInfo typeInfo = computeType(beforeType, false);
+    token = typeInfo.skipType(beforeType);
+    next = token.next;
+
+    if (next.isIdentifier) {
+      if (optional('<', next.next) || optional('(', next.next)) {
+        // Found an expression or local function declaration.
+        // TODO(danrubel): Process local function declarations.
+        return start;
+      }
+    }
+
+    if (token == start) {
+      // If no annotation, modifier, or type, and this is not a local function
+      // then return without consuming any tokens because this is not
+      // a local declaration.
+      return start;
+    }
+
+    if (!optional('@', start.next)) {
+      listener.beginMetadataStar(start.next);
+      listener.endMetadataStar(0);
+    }
+    token = typeInfo.parseType(beforeType, this);
+    next = token.next;
+
+    // If there is not an identifier, then allow ensureIdentifier to report an
+    // error and don't report errors here.
+    if (next.isIdentifier) {
+      if (varFinalOrConst == null) {
+        if (typeInfo == noTypeInfo) {
+          reportRecoverableError(next, fasta.messageMissingConstFinalVarOrType);
+        }
+      } else if (optional('var', varFinalOrConst)) {
+        if (typeInfo != noTypeInfo) {
+          reportRecoverableError(varFinalOrConst, fasta.messageTypeAfterVar);
+        }
+      }
+    }
+
+    listener.beginVariablesDeclaration(next, varFinalOrConst);
+    return token;
   }
 
-  Token parseVariablesDeclarationMaybeSemicolon(
-      Token token, bool endWithSemicolon) {
+  Token parseVariablesDeclaration(Token token) {
+    token = parseMetadataStar(token);
     Token next = token.next;
 
     TypeContinuation typeContinuation;
@@ -5544,16 +5629,30 @@
       }
     }
 
-    token = parseType(token, typeContinuation ?? TypeContinuation.Required,
-        null, MemberKind.Local);
-    return parseVariablesDeclarationMaybeSemicolonRest(
-        token, varFinalOrConst, endWithSemicolon);
+    TypeInfo typeInfo = computeType(token, false);
+    if (varFinalOrConst == null) {
+      if (typeInfo == noTypeInfo) {
+        // If there is no modifer, no type, and no identifier
+        // then let parseVariablesDeclarationMaybeSemicolonRest
+        // report a missing identifier rather than reporting two errors.
+        if (token.next.isIdentifier) {
+          reportRecoverableError(
+              token.next, fasta.messageMissingConstFinalVarOrType);
+        }
+      }
+    } else if (optional('var', varFinalOrConst)) {
+      if (typeInfo != noTypeInfo) {
+        reportRecoverableError(token.next, fasta.messageTypeAfterVar);
+      }
+    }
+    token = typeInfo.parseType(token, this);
+
+    listener.beginVariablesDeclaration(token.next, varFinalOrConst);
+    return parseVariablesDeclarationRest(token, true);
   }
 
-  Token parseVariablesDeclarationMaybeSemicolonRest(
-      Token token, Token varFinalOrConst, bool endWithSemicolon) {
+  Token parseVariablesDeclarationRest(Token token, bool endWithSemicolon) {
     int count = 1;
-    listener.beginVariablesDeclaration(token.next, varFinalOrConst);
     token = parseOptionallyInitializedIdentifier(token);
     while (optional(',', token.next)) {
       token = parseOptionallyInitializedIdentifier(token.next);
@@ -5646,57 +5745,47 @@
     }
     token = leftParenthesis;
 
-    Token beforeIdentifier;
-    final String stringValue = token.next.stringValue;
-    if (identical(stringValue, ';')) {
+    token = parseLocalDeclarationStartOpt(token);
+    Token beforeIdentifier = token;
+    if (token != leftParenthesis) {
+      token = parseVariablesDeclarationRest(token, false);
+    } else if (optional(';', token.next)) {
       listener.handleNoExpression(token.next);
     } else {
-      if (identical('@', stringValue) ||
-          identical('var', stringValue) ||
-          identical('final', stringValue) ||
-          identical('const', stringValue)) {
-        token = parseMetadataStar(token);
-        beforeIdentifier = skipTypeReferenceOpt(token, false);
-        // TODO(ahe, danrubel): Generate type events and call
-        // parseVariablesDeclarationNoSemicolonRest instead.
-        token = parseVariablesDeclarationMaybeSemicolon(token, false);
-      } else {
-        beforeIdentifier = skipTypeReferenceOpt(token, false);
-        if (token == beforeIdentifier) {
-          // No type found, just parse expression
-          token = parseExpression(token);
-        } else {
-          // TODO(ahe, danrubel): Generate type events and call
-          // parseVariablesDeclarationNoSemicolonRest instead.
-          token = parseMetadataStar(token);
-          token = parseVariablesDeclarationMaybeSemicolon(token, false);
-        }
-      }
+      token = parseExpression(token);
     }
 
     Token next = token.next;
-    if (optional('in', next)) {
-      if (awaitToken != null && !inAsync) {
-        reportRecoverableError(next, fasta.messageAwaitForNotAsync);
+    if (!optional('in', next)) {
+      if (optional(':', next)) {
+        reportRecoverableError(next, fasta.messageColonInPlaceOfIn);
+        // Fall through to process `for ( ... in ... )`
+      } else {
+        // Process `for ( ... ; ... ; ... )`
+        if (awaitToken != null) {
+          reportRecoverableError(awaitToken, fasta.messageInvalidAwaitFor);
+        }
+        return parseForRest(token, forKeyword, leftParenthesis);
       }
-      if (beforeIdentifier != null &&
-          optional('=', beforeIdentifier.next.next)) {
-        reportRecoverableError(beforeIdentifier.next.next,
-            fasta.messageInitializedVariableInForEach);
-      }
-      return parseForInRest(awaitToken, forKeyword, leftParenthesis, token);
-    } else if (optional(':', next)) {
-      reportRecoverableError(next, fasta.messageColonInPlaceOfIn);
-      if (awaitToken != null && !inAsync) {
-        reportRecoverableError(next, fasta.messageAwaitForNotAsync);
-      }
-      return parseForInRest(awaitToken, forKeyword, leftParenthesis, token);
-    } else {
-      if (awaitToken != null) {
-        reportRecoverableError(awaitToken, fasta.messageInvalidAwaitFor);
-      }
-      return parseForRest(forKeyword, leftParenthesis, token);
     }
+
+    // Process `for ( ... in ... )`
+    Token identifier = beforeIdentifier.next;
+    if (!identifier.isIdentifier) {
+      reportRecoverableErrorWithToken(
+          identifier, fasta.templateExpectedIdentifier);
+    } else if (identifier != token) {
+      if (optional('=', identifier.next)) {
+        reportRecoverableError(
+            identifier.next, fasta.messageInitializedVariableInForEach);
+      } else {
+        reportRecoverableErrorWithToken(
+            identifier.next, fasta.templateUnexpectedToken);
+      }
+    } else if (awaitToken != null && !inAsync) {
+      reportRecoverableError(next, fasta.messageAwaitForNotAsync);
+    }
+    return parseForInRest(token, awaitToken, forKeyword, leftParenthesis);
   }
 
   /// This method parses the portion of the forLoopParts that starts with the
@@ -5709,8 +5798,7 @@
   ///   identifier 'in' expression
   /// ;
   /// ```
-  Token parseForRest(Token forToken, Token leftParenthesis, Token token) {
-    // TODO(brianwilkerson): Consider moving `token` to be the first parameter.
+  Token parseForRest(Token token, Token forToken, Token leftParenthesis) {
     Token leftSeparator = ensureSemicolon(token);
     if (optional(';', leftSeparator.next)) {
       token = parseEmptyStatement(leftSeparator);
@@ -5730,7 +5818,10 @@
         break;
       }
     }
-    expect(')', token);
+    if (token != leftParenthesis.endGroup) {
+      reportRecoverableErrorWithToken(token, fasta.templateUnexpectedToken);
+      token = leftParenthesis.endGroup;
+    }
     listener.beginForStatementBody(token.next);
     LoopState savedLoopState = loopState;
     loopState = LoopState.InsideLoop;
@@ -5754,8 +5845,7 @@
   /// ;
   /// ```
   Token parseForInRest(
-      Token awaitToken, Token forKeyword, Token leftParenthesis, Token token) {
-    // TODO(brianwilkerson): Consider moving `token` to be the first parameter.
+      Token token, Token awaitToken, Token forKeyword, Token leftParenthesis) {
     Token inKeyword = token.next;
     assert(optional('in', inKeyword) || optional(':', inKeyword));
     listener.beginForInExpression(inKeyword.next);
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info.dart b/pkg/front_end/lib/src/fasta/parser/type_info.dart
index 8a012ce..d282fcb 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info.dart
@@ -35,12 +35,13 @@
 abstract class TypeInfo {
   /// Call this function when it's known that the token after [token] is a type.
   /// This function will call the appropriate event methods on the [Parser]'s
-  /// listener to handle the type.
+  /// listener to handle the type. This may modify the token stream
+  /// when parsing `>>` in valid code or during recovery.
   Token parseType(Token token, Parser parser);
 
   /// Call this function with the [token] before the type to obtain
   /// the last token in the type. If there is no type, then this method
-  /// will return [token].
+  /// will return [token]. This does not modify the token stream.
   Token skipType(Token token);
 }
 
@@ -85,7 +86,7 @@
 }
 
 /// Called by the parser to obtain information about a possible type reference
-/// that follows [token].
+/// that follows [token]. This does not modify the token stream.
 TypeInfo computeType(final Token token, bool required) {
   Token next = token.next;
   if (!isValidTypeReference(next)) {
@@ -238,9 +239,17 @@
       listener.endFunctionType(functionToken, token.next);
     }
 
-    assert(
-        identical(token, end) || (optional('>', token) && optional('>>', end)));
-    return token;
+    // There are two situations in which the [token] != [end]:
+    // Valid code:    identifier `<` identifier `<` identifier `>>`
+    //    where `>>` is replaced by two tokens.
+    // Invalid code:  identifier `<` identifier identifier `>`
+    //    where a synthetic `>` is inserted between the identifiers.
+    assert(identical(token, end) || optional('>', token));
+
+    // During recovery, [token] may be a synthetic that was inserted in the
+    // middle of the type reference. In this situation, return [end] so that it
+    // matches [skipType], and so that the next token to be parsed is correct.
+    return token.isSynthetic ? end : token;
   }
 
   @override
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 fb478c7..83396f3 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -15,7 +15,7 @@
         Expression,
         Library,
         LibraryDependency,
-        Program,
+        Component,
         Supertype;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
@@ -544,7 +544,7 @@
     ticker.logMs("Checked restricted supertypes");
   }
 
-  void buildProgram() {
+  void buildComponent() {
     builders.forEach((Uri uri, LibraryBuilder library) {
       if (library.loader == this) {
         SourceLibraryBuilder sourceLibrary = library;
@@ -554,10 +554,10 @@
         }
       }
     });
-    ticker.logMs("Built program");
+    ticker.logMs("Built component");
   }
 
-  Program computeFullProgram() {
+  Component computeFullProgram() {
     Set<Library> libraries = new Set<Library>();
     List<Library> workList = <Library>[];
     builders.forEach((Uri uri, LibraryBuilder library) {
@@ -575,7 +575,7 @@
         }
       }
     }
-    return new Program()..libraries.addAll(libraries);
+    return new Component()..libraries.addAll(libraries);
   }
 
   void computeHierarchy() {
@@ -614,8 +614,8 @@
 
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
 
-  void computeCoreTypes(Program program) {
-    coreTypes = new CoreTypes(program);
+  void computeCoreTypes(Component component) {
+    coreTypes = new CoreTypes(component);
     ticker.logMs("Computed core types");
   }
 
diff --git a/pkg/front_end/lib/src/fasta/target.dart b/pkg/front_end/lib/src/fasta/target.dart
index c49da71..30b3754 100644
--- a/pkg/front_end/lib/src/fasta/target.dart
+++ b/pkg/front_end/lib/src/fasta/target.dart
@@ -12,7 +12,7 @@
 /// A compilation target.
 ///
 /// A target reads source files with [read], builds outlines when
-/// [buildOutlines] is called and builds the full program when [buildProgram]
+/// [buildOutlines] is called and builds the full component when [buildComponent]
 /// is called.
 abstract class Target {
   final Ticker ticker;
@@ -23,8 +23,8 @@
   void read(Uri uri);
 
   /// Build and return outlines for all libraries.
-  Future<Program> buildOutlines();
+  Future<Component> buildOutlines();
 
-  /// Build and return the full program for all libraries.
-  Future<Program> buildProgram();
+  /// Build and return the full component for all libraries.
+  Future<Component> buildComponent();
 }
diff --git a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
index 47a7d33..49b1793 100644
--- a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
+++ b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
@@ -13,7 +13,7 @@
 
 import 'dart:typed_data' show Uint8List;
 
-import 'package:kernel/ast.dart' show Library, Program;
+import 'package:kernel/ast.dart' show Library, Component;
 
 import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
 
@@ -21,7 +21,7 @@
 
 import 'package:kernel/error_formatter.dart' show ErrorFormatter;
 
-import 'package:kernel/kernel.dart' show loadProgramFromBinary;
+import 'package:kernel/kernel.dart' show loadComponentFromBinary;
 
 import 'package:kernel/naive_type_checker.dart' show StrongModeTypeChecker;
 
@@ -42,16 +42,16 @@
 
 import '../compiler_context.dart';
 
-import '../kernel/verifier.dart' show verifyProgram;
+import '../kernel/verifier.dart' show verifyComponent;
 
-class Print extends Step<Program, Program, ChainContext> {
+class Print extends Step<Component, Component, ChainContext> {
   const Print();
 
   String get name => "print";
 
-  Future<Result<Program>> run(Program program, _) async {
+  Future<Result<Component>> run(Component component, _) async {
     StringBuffer sb = new StringBuffer();
-    for (Library library in program.libraries) {
+    for (Library library in component.libraries) {
       Printer printer = new Printer(sb);
       if (library.importUri.scheme != "dart" &&
           library.importUri.scheme != "package") {
@@ -59,53 +59,59 @@
       }
     }
     print("$sb");
-    return pass(program);
+    return pass(component);
   }
 }
 
-class Verify extends Step<Program, Program, ChainContext> {
+class Verify extends Step<Component, Component, ChainContext> {
   final bool fullCompile;
 
   const Verify(this.fullCompile);
 
   String get name => "verify";
 
-  Future<Result<Program>> run(Program program, ChainContext context) async {
+  Future<Result<Component>> run(
+      Component component, ChainContext context) async {
     var options = new ProcessedOptions(new CompilerOptions());
     return await CompilerContext.runWithOptions(options, (_) async {
-      var errors = verifyProgram(program, isOutline: !fullCompile);
+      var errors = verifyComponent(component,
+          isOutline: !fullCompile, skipPlatform: true);
       if (errors.isEmpty) {
-        return pass(program);
+        return pass(component);
       } else {
-        return new Result<Program>(
+        return new Result<Component>(
             null, context.expectationSet["VerificationError"], errors, null);
       }
     });
   }
 }
 
-class TypeCheck extends Step<Program, Program, ChainContext> {
+class TypeCheck extends Step<Component, Component, ChainContext> {
   const TypeCheck();
 
   String get name => "typeCheck";
 
-  Future<Result<Program>> run(Program program, ChainContext context) async {
+  Future<Result<Component>> run(
+      Component component, ChainContext context) async {
     var errorFormatter = new ErrorFormatter();
     var checker =
-        new StrongModeTypeChecker(errorFormatter, program, ignoreSdk: true);
-    checker.checkProgram(program);
+        new StrongModeTypeChecker(errorFormatter, component, ignoreSdk: true);
+    checker.checkComponent(component);
     if (errorFormatter.numberOfFailures == 0) {
-      return pass(program);
+      return pass(component);
     } else {
       errorFormatter.failures.forEach(print);
       print('------- Found ${errorFormatter.numberOfFailures} errors -------');
-      return new Result<Program>(null, context.expectationSet["TypeCheckError"],
-          '${errorFormatter.numberOfFailures} type errors', null);
+      return new Result<Component>(
+          null,
+          context.expectationSet["TypeCheckError"],
+          '${errorFormatter.numberOfFailures} type errors',
+          null);
     }
   }
 }
 
-class MatchExpectation extends Step<Program, Program, ChainContext> {
+class MatchExpectation extends Step<Component, Component, ChainContext> {
   final String suffix;
 
   // TODO(ahe): This is true by default which doesn't match well with the class
@@ -116,8 +122,8 @@
 
   String get name => "match expectations";
 
-  Future<Result<Program>> run(Program program, _) async {
-    Library library = program.libraries
+  Future<Result<Component>> run(Component component, _) async {
+    Library library = component.libraries
         .firstWhere((Library library) => library.importUri.scheme != "dart");
     Uri uri = library.importUri;
     Uri base = uri.resolve(".");
@@ -134,37 +140,37 @@
           return fail(null, "$uri doesn't match ${expectedFile.uri}\n$diff");
         }
       } else {
-        return pass(program);
+        return pass(component);
       }
     }
     if (updateExpectations) {
       await openWrite(expectedFile.uri, (IOSink sink) {
         sink.writeln(actual.trim());
       });
-      return pass(program);
+      return pass(component);
     } else {
-      return fail(program, """
+      return fail(component, """
 Please create file ${expectedFile.path} with this content:
 $actual""");
     }
   }
 }
 
-class WriteDill extends Step<Program, Uri, ChainContext> {
+class WriteDill extends Step<Component, Uri, ChainContext> {
   const WriteDill();
 
   String get name => "write .dill";
 
-  Future<Result<Uri>> run(Program program, _) async {
+  Future<Result<Uri>> run(Component component, _) async {
     Directory tmp = await Directory.systemTemp.createTemp();
     Uri uri = tmp.uri.resolve("generated.dill");
     File generated = new File.fromUri(uri);
     IOSink sink = generated.openWrite();
     try {
       try {
-        new BinaryPrinter(sink).writeProgramFile(program);
+        new BinaryPrinter(sink).writeComponentFile(component);
       } finally {
-        program.unbindCanonicalNames();
+        component.unbindCanonicalNames();
       }
     } catch (e, s) {
       return fail(uri, e, s);
@@ -183,7 +189,7 @@
 
   Future<Result<Uri>> run(Uri uri, _) async {
     try {
-      loadProgramFromBinary(uri.toFilePath());
+      loadComponentFromBinary(uri.toFilePath());
     } catch (e, s) {
       return fail(uri, e, s);
     }
@@ -191,34 +197,34 @@
   }
 }
 
-class Copy extends Step<Program, Program, ChainContext> {
+class Copy extends Step<Component, Component, ChainContext> {
   const Copy();
 
-  String get name => "copy program";
+  String get name => "copy component";
 
-  Future<Result<Program>> run(Program program, _) async {
+  Future<Result<Component>> run(Component component, _) async {
     BytesCollector sink = new BytesCollector();
-    new BinaryPrinter(sink).writeProgramFile(program);
-    program.unbindCanonicalNames();
+    new BinaryPrinter(sink).writeComponentFile(component);
+    component.unbindCanonicalNames();
     Uint8List bytes = sink.collect();
-    new BinaryBuilder(bytes).readProgram(program);
-    return pass(program);
+    new BinaryBuilder(bytes).readComponent(component);
+    return pass(component);
   }
 }
 
 /// A `package:testing` step that runs the `package:front_end` compiler to
-/// generate a kernel program for an individual file.
+/// generate a kernel component for an individual file.
 ///
 /// Most options are hard-coded, but if necessary they could be moved to the
 /// [CompileContext] object in the future.
-class Compile extends Step<TestDescription, Program, CompileContext> {
+class Compile extends Step<TestDescription, Component, CompileContext> {
   const Compile();
 
   String get name => "fasta compilation";
 
-  Future<Result<Program>> run(
+  Future<Result<Component>> run(
       TestDescription description, CompileContext context) async {
-    Result<Program> result;
+    Result<Component> result;
     reportError(CompilationMessage error) {
       result ??= fail(null, error.message);
     }
@@ -240,7 +246,7 @@
         computePlatformBinariesLocation().resolve("vm_platform.dill"),
       ];
     }
-    Program p = await kernelForProgram(description.uri, options);
+    Component p = await kernelForProgram(description.uri, options);
     return result ??= pass(p);
   }
 }
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 0f78fba..87723e6 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
@@ -229,7 +229,7 @@
   /// corresponding fields.
   void finishTopLevelInitializingFormals();
 
-  /// Gets ready to do top level type inference for the program having the given
+  /// Gets ready to do top level type inference for the component having the given
   /// [hierarchy], using the given [coreTypes].
   void prepareTopLevel(CoreTypes coreTypes, ClassHierarchy hierarchy);
 
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
index d40ee3d..fa4b1ea 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
@@ -16,7 +16,7 @@
 /// methods maintain a linked list of [TypePromotionFact] objects tracking what
 /// is known about the state of each variable at the current point in the code,
 /// as well as a linked list of [TypePromotionScope] objects tracking the
-/// program's nesting structure.  Whenever a variable is read, the current
+/// component's nesting structure.  Whenever a variable is read, the current
 /// [TypePromotionFact] and [TypePromotionScope] are recorded for later use.
 ///
 /// During type inference, the [TypeInferrer] calls back into this class to ask
@@ -473,7 +473,7 @@
 }
 
 /// A single fact which is known to the type promotion engine about the state of
-/// a variable (or about the flow control of the program).
+/// a variable (or about the flow control of the component).
 ///
 /// The type argument V represents is the class which represents local variable
 /// declarations.
@@ -481,14 +481,14 @@
 /// Facts are linked together into linked lists via the [previous] pointer into
 /// a data structure called a "fact chain" (or sometimes a "fact state"), which
 /// represents all facts that are known to hold at a certain point in the
-/// program.
+/// component.
 ///
-/// The fact is said to "apply" to a given point in the execution of the program
+/// The fact is said to "apply" to a given point in the execution of the component
 /// if the fact is part of the current fact state at the point the parser
-/// reaches that point in the program.
+/// reaches that point in the component.
 ///
 /// Note: just because a fact "applies" to a given point in the execution of the
-/// program doesn't mean a type will be promoted--it simply means that the fact
+/// component doesn't mean a type will be promoted--it simply means that the fact
 /// was deduced at a previous point in the straight line execution of the code.
 /// It's possible that the fact will be overshadowed by a later fact, or its
 /// effect will be cancelled by a later assignment.  The final detemination of
diff --git a/pkg/front_end/lib/src/incremental/kernel_driver.dart b/pkg/front_end/lib/src/incremental/kernel_driver.dart
index 3bbb34f..9038870 100644
--- a/pkg/front_end/lib/src/incremental/kernel_driver.dart
+++ b/pkg/front_end/lib/src/incremental/kernel_driver.dart
@@ -64,7 +64,7 @@
   /// Options used by the kernel compiler.
   final ProcessedOptions _options;
 
-  /// The optional SDK outline as a serialized program.
+  /// The optional SDK outline as a serialized component.
   /// If provided, the driver will not attempt to read SDK files.
   final List<int> _sdkOutlineBytes;
 
@@ -93,7 +93,7 @@
 
   /// The optional SDK outline loaded from [_sdkOutlineBytes].
   /// Might be `null` if the bytes are not provided, or if not loaded yet.
-  Program _sdkOutline;
+  Component _sdkOutline;
 
   /// The salt to mix into all hashes used as keys for serialized data.
   List<int> _salt;
@@ -368,9 +368,9 @@
       CanonicalName nameRoot, List<LibraryCycleResult> results) {
     var coreLibraries =
         results.first.libraryResults.map((l) => l.library).toList();
-    var program = new Program(nameRoot: nameRoot, libraries: coreLibraries);
+    var component = new Component(nameRoot: nameRoot, libraries: coreLibraries);
     return new TypeEnvironment(
-        new CoreTypes(program), new ClassHierarchy(program));
+        new CoreTypes(component), new ClassHierarchy(component));
   }
 
   /// Ensure that [dillTarget] includes the [cycle] libraries.  It already
@@ -405,9 +405,9 @@
         }
       }
 
-      Future<Null> appendNewDillLibraries(Program program) async {
+      Future<Null> appendNewDillLibraries(Component component) async {
         dillTarget.loader
-            .appendLibraries(program, filter: libraryUris.contains);
+            .appendLibraries(component, filter: libraryUris.contains);
         await dillTarget.buildOutlines();
       }
 
@@ -417,15 +417,15 @@
         List<int> bytes = _byteStore.get(kernelKey);
         if (bytes != null) {
           return _logger.runAsync('Read serialized libraries', () async {
-            var program = new Program(nameRoot: nameRoot);
-            _readProgram(program, bytes);
-            await appendNewDillLibraries(program);
+            var component = new Component(nameRoot: nameRoot);
+            _readProgram(component, bytes);
+            await appendNewDillLibraries(component);
 
             return new LibraryCycleResult(
                 cycle,
                 signature,
-                program.uriToSource,
-                program.libraries
+                component.uriToSource,
+                component.libraries
                     // TODO report errors here
                     .map((l) => new LibraryResult(l, []))
                     .toList());
@@ -441,19 +441,19 @@
         kernelTarget.read(library.uri);
       }
 
-      // Compile the cycle libraries into a new full program.
-      Program program = await _logger
+      // Compile the cycle libraries into a new full component.
+      Component component = await _logger
           .runAsync('Compile ${cycle.libraries.length} libraries', () async {
         await kernelTarget.buildOutlines(nameRoot: nameRoot);
-        return await kernelTarget.buildProgram();
+        return await kernelTarget.buildComponent();
       });
 
       _testView.compiledCycles.add(cycle);
 
       // Add newly compiled libraries into DILL.
-      await appendNewDillLibraries(program);
+      await appendNewDillLibraries(component);
 
-      List<Library> kernelLibraries = program.libraries
+      List<Library> kernelLibraries = component.libraries
           .where((library) => libraryUris.contains(library.importUri))
           .toList();
 
@@ -469,23 +469,23 @@
       // Remove source for libraries outside of the cycle.
       {
         var urisToRemoveSources = <Uri>[];
-        for (var uri in program.uriToSource.keys) {
+        for (var uri in component.uriToSource.keys) {
           if (!cycleFileUris.contains(uri)) {
             urisToRemoveSources.add(uri);
           }
         }
-        urisToRemoveSources.forEach(program.uriToSource.remove);
+        urisToRemoveSources.forEach(component.uriToSource.remove);
       }
 
       _logger.run('Serialize ${kernelLibraries.length} libraries', () {
         List<int> bytes =
-            serializeProgram(program, filter: kernelLibraries.contains);
+            serializeComponent(component, filter: kernelLibraries.contains);
         _byteStore.put(kernelKey, bytes);
         _logger.writeln('Stored ${bytes.length} bytes.');
       });
 
       return new LibraryCycleResult(
-          cycle, signature, program.uriToSource, kernelLibrariesResults);
+          cycle, signature, component.uriToSource, kernelLibrariesResults);
     });
   }
 
@@ -544,7 +544,7 @@
   Future<Null> _loadSdkOutline() async {
     if (_sdkOutlineBytes != null && _sdkOutline == null) {
       await _logger.runAsync('Load SDK outline from bytes', () async {
-        _sdkOutline = loadProgramFromBytes(_sdkOutlineBytes);
+        _sdkOutline = loadComponentFromBytes(_sdkOutlineBytes);
         // Configure the file system state to skip the outline libraries.
         for (var outlineLibrary in _sdkOutline.libraries) {
           _fsState.skipSdkLibraries.add(outlineLibrary.importUri);
@@ -553,17 +553,17 @@
     }
   }
 
-  /// Read libraries from the given [bytes] into the [program], using the
-  /// configured metadata factory.  The [program] must be ready to read these
-  /// libraries, i.e. either the [bytes] represent a full program with all
-  /// dependencies, or the [program] already has all required dependencies.
-  void _readProgram(Program program, List<int> bytes) {
+  /// Read libraries from the given [bytes] into the [component], using the
+  /// configured metadata factory.  The [component] must be ready to read these
+  /// libraries, i.e. either the [bytes] represent a full component with all
+  /// dependencies, or the [component] already has all required dependencies.
+  void _readProgram(Component component, List<int> bytes) {
     if (_metadataFactory != null) {
       var repository = _metadataFactory.newRepositoryForReading();
-      program.addMetadataRepository(repository);
-      new BinaryBuilderWithMetadata(bytes).readSingleFileProgram(program);
+      component.addMetadataRepository(repository);
+      new BinaryBuilderWithMetadata(bytes).readSingleFileComponent(component);
     } else {
-      new BinaryBuilder(bytes).readProgram(program);
+      new BinaryBuilder(bytes).readComponent(component);
     }
   }
 
@@ -662,7 +662,7 @@
   MetadataCollector newCollector();
 
   /// Return a new [MetadataRepository] instance to read metadata while
-  /// reading a [Program] for a library cycle.
+  /// reading a [Component] for a library cycle.
   MetadataRepository newRepositoryForReading();
 }
 
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index a41e93a..4761b9a 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -8,7 +8,7 @@
 import 'dart:async' show Future;
 import 'dart:async';
 
-import 'package:kernel/kernel.dart' show Program, CanonicalName;
+import 'package:kernel/kernel.dart' show Component, CanonicalName;
 
 import 'base/processed_options.dart';
 import 'fasta/severity.dart' show Severity;
@@ -25,19 +25,19 @@
 /// `package:front_end/src/api_prototype/summary_generator.dart` APIs.
 Future<CompilerResult> generateKernel(ProcessedOptions options,
     {bool buildSummary: false,
-    bool buildProgram: true,
+    bool buildComponent: true,
     bool truncateSummary: false}) async {
   return await CompilerContext.runWithOptions(options, (_) async {
     return await generateKernelInternal(
         buildSummary: buildSummary,
-        buildProgram: buildProgram,
+        buildComponent: buildComponent,
         truncateSummary: truncateSummary);
   });
 }
 
 Future<CompilerResult> generateKernelInternal(
     {bool buildSummary: false,
-    bool buildProgram: true,
+    bool buildComponent: true,
     bool truncateSummary: false}) async {
   var options = CompilerContext.current.options;
   var fs = options.fileSystem;
@@ -50,8 +50,8 @@
     var dillTarget =
         new DillTarget(options.ticker, uriTranslator, options.target);
 
-    Set<Uri> externalLibs(Program program) {
-      return program.libraries
+    Set<Uri> externalLibs(Component component) {
+      return component.libraries
           .where((lib) => lib.isExternal)
           .map((lib) => lib.importUri)
           .toSet();
@@ -82,7 +82,7 @@
       lib.isExternal = true;
     });
 
-    // Linked dependencies are meant to be part of the program so they are not
+    // Linked dependencies are meant to be part of the component so they are not
     // marked external.
     for (var dependency in await options.loadLinkDependencies(nameRoot)) {
       var excluded = externalLibs(dependency);
@@ -94,54 +94,55 @@
 
     var kernelTarget = new KernelTarget(fs, false, dillTarget, uriTranslator);
     options.inputs.forEach(kernelTarget.read);
-    Program summaryProgram =
+    Component summaryProgram =
         await kernelTarget.buildOutlines(nameRoot: nameRoot);
     List<int> summary = null;
     if (buildSummary) {
       if (options.verify) {
-        for (var error in verifyProgram(summaryProgram)) {
+        for (var error in verifyComponent(summaryProgram)) {
           options.report(error, Severity.error);
         }
       }
       if (options.debugDump) {
-        printProgramText(summaryProgram,
+        printComponentText(summaryProgram,
             libraryFilter: kernelTarget.isSourceLibrary);
       }
 
-      // Copy the program to exclude the uriToSource map from the summary.
+      // Copy the component to exclude the uriToSource map from the summary.
       //
       // Note: we don't pass the library argument to the constructor to
       // preserve the the libraries parent pointer (it should continue to point
-      // to the program within KernelTarget).
-      var trimmedSummaryProgram = new Program(nameRoot: summaryProgram.root)
+      // to the component within KernelTarget).
+      var trimmedSummaryProgram = new Component(nameRoot: summaryProgram.root)
         ..libraries.addAll(truncateSummary
             ? kernelTarget.loader.libraries
             : summaryProgram.libraries);
       trimmedSummaryProgram.metadata.addAll(summaryProgram.metadata);
 
       // As documented, we only run outline transformations when we are building
-      // summaries without building a full program (at this time, that's
+      // summaries without building a full component (at this time, that's
       // the only need we have for these transformations).
-      if (!buildProgram) {
+      if (!buildComponent) {
         options.target.performOutlineTransformations(trimmedSummaryProgram);
         options.ticker.logMs("Transformed outline");
       }
-      summary = serializeProgram(trimmedSummaryProgram);
+      summary = serializeComponent(trimmedSummaryProgram);
       options.ticker.logMs("Generated outline");
     }
 
-    Program program;
-    if (buildProgram && kernelTarget.errors.isEmpty) {
-      program = await kernelTarget.buildProgram(verify: options.verify);
+    Component component;
+    if (buildComponent && kernelTarget.errors.isEmpty) {
+      component = await kernelTarget.buildComponent(verify: options.verify);
       if (options.debugDump) {
-        printProgramText(program, libraryFilter: kernelTarget.isSourceLibrary);
+        printComponentText(component,
+            libraryFilter: kernelTarget.isSourceLibrary);
       }
-      options.ticker.logMs("Generated program");
+      options.ticker.logMs("Generated component");
     }
 
     return new CompilerResult(
         summary: summary,
-        program: program,
+        component: component,
         deps: kernelTarget.loader.getDependencies());
   } on deprecated_InputError catch (e) {
     options.report(
@@ -157,8 +158,8 @@
   /// The generated summary bytes, if it was requested.
   final List<int> summary;
 
-  /// The generated program, if it was requested.
-  final Program program;
+  /// The generated component, if it was requested.
+  final Component component;
 
   /// Dependencies traversed by the compiler. Used only for generating
   /// dependency .GN files in the dart-sdk build system.
@@ -166,5 +167,5 @@
   /// using the compiler itself.
   final List<Uri> deps;
 
-  CompilerResult({this.summary, this.program, this.deps});
+  CompilerResult({this.summary, this.component, this.deps});
 }
diff --git a/pkg/front_end/lib/src/testing/compiler_common.dart b/pkg/front_end/lib/src/testing/compiler_common.dart
index 8e6a904..0193e73 100644
--- a/pkg/front_end/lib/src/testing/compiler_common.dart
+++ b/pkg/front_end/lib/src/testing/compiler_common.dart
@@ -7,10 +7,10 @@
 
 import 'dart:async' show Future;
 
-import 'package:kernel/ast.dart' show Library, Program;
+import 'package:kernel/ast.dart' show Library, Component;
 
 import '../api_prototype/front_end.dart'
-    show CompilerOptions, kernelForBuildUnit, kernelForProgram, summaryFor;
+    show CompilerOptions, kernelForComponent, kernelForProgram, summaryFor;
 
 import '../api_prototype/memory_file_system.dart' show MemoryFileSystem;
 
@@ -26,7 +26,7 @@
 /// compiles the entry whose name is [fileName].
 ///
 /// Wraps [kernelForProgram] with some default testing options (see [setup]).
-Future<Program> compileScript(dynamic scriptOrSources,
+Future<Component> compileScript(dynamic scriptOrSources,
     {fileName: 'main.dart',
     List<String> inputSummaries: const [],
     List<String> linkedDependencies: const [],
@@ -44,17 +44,17 @@
   return await kernelForProgram(toTestUri(fileName), options);
 }
 
-/// Generate a program for a modular complation unit.
+/// Generate a component for a modular complation unit.
 ///
-/// Wraps [kernelForBuildUnit] with some default testing options (see [setup]).
-Future<Program> compileUnit(List<String> inputs, Map<String, dynamic> sources,
+/// Wraps [kernelForComponent] with some default testing options (see [setup]).
+Future<Component> compileUnit(List<String> inputs, Map<String, dynamic> sources,
     {List<String> inputSummaries: const [],
     List<String> linkedDependencies: const [],
     CompilerOptions options}) async {
   options ??= new CompilerOptions();
   await setup(options, sources,
       inputSummaries: inputSummaries, linkedDependencies: linkedDependencies);
-  return await kernelForBuildUnit(inputs.map(toTestUri).toList(), options);
+  return await kernelForComponent(inputs.map(toTestUri).toList(), options);
 }
 
 /// Generate a summary for a modular complation unit.
@@ -136,8 +136,8 @@
 bool isDartCoreLibrary(Library lib) => isDartCore(lib.importUri);
 bool isDartCore(Uri uri) => uri.scheme == 'dart' && uri.path == 'core';
 
-/// Find a library in [program] whose Uri ends with the given [suffix]
-Library findLibrary(Program program, String suffix) {
-  return program.libraries
+/// Find a library in [component] whose Uri ends with the given [suffix]
+Library findLibrary(Component component, String suffix) {
+  return component.libraries
       .firstWhere((lib) => lib.importUri.path.endsWith(suffix));
 }
diff --git a/pkg/front_end/test/fasta/ambiguous_export_test.dart b/pkg/front_end/test/fasta/ambiguous_export_test.dart
index 0189766..8123c39 100644
--- a/pkg/front_end/test/fasta/ambiguous_export_test.dart
+++ b/pkg/front_end/test/fasta/ambiguous_export_test.dart
@@ -17,7 +17,7 @@
 import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
 
 import 'package:kernel/ast.dart'
-    show Field, Library, Name, Program, StringLiteral;
+    show Field, Library, Name, Component, StringLiteral;
 
 main() async {
   await asyncTest(() async {
@@ -25,11 +25,11 @@
     Field field = new Field(new Name("_exports#", library),
         initializer: new StringLiteral('{"main":"Problem with main"}'));
     library.addMember(field);
-    Program program = new Program(libraries: <Library>[library]);
+    Component component = new Component(libraries: <Library>[library]);
     await CompilerContext.runWithDefaultOptions((CompilerContext c) async {
       DillTarget target =
           new DillTarget(c.options.ticker, null, c.options.target);
-      target.loader.appendLibraries(program);
+      target.loader.appendLibraries(component);
       DillLibraryBuilder builder = target.loader.read(library.importUri, -1);
       await target.loader.buildOutline(builder);
       builder.finalizeExports();
diff --git a/pkg/front_end/test/fasta/assert_locations_test.dart b/pkg/front_end/test/fasta/assert_locations_test.dart
index b8bcf7e..a2e7355 100644
--- a/pkg/front_end/test/fasta/assert_locations_test.dart
+++ b/pkg/front_end/test/fasta/assert_locations_test.dart
@@ -9,7 +9,7 @@
 import 'package:expect/expect.dart' show Expect;
 
 import 'package:kernel/ast.dart'
-    show Program, RecursiveVisitor, Procedure, AssertStatement;
+    show Component, RecursiveVisitor, Procedure, AssertStatement;
 
 import "package:front_end/src/api_prototype/compiler_options.dart"
     show CompilerOptions;
@@ -142,7 +142,7 @@
         Expect.fail("Unexpected error: $formatted");
       }
       ..strongMode = true;
-    Program p = await compileScript(test.source,
+    Component p = await compileScript(test.source,
         options: options, fileName: 'synthetic-test.dart');
     Expect.isNotNull(p);
     VerifyingVisitor visitor = new VerifyingVisitor(test);
diff --git a/pkg/front_end/test/fasta/bootstrap_test.dart b/pkg/front_end/test/fasta/bootstrap_test.dart
index 524ec46..77e7cab 100644
--- a/pkg/front_end/test/fasta/bootstrap_test.dart
+++ b/pkg/front_end/test/fasta/bootstrap_test.dart
@@ -12,9 +12,9 @@
 
 import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
 
-import 'package:kernel/ast.dart' show Program;
+import 'package:kernel/ast.dart' show Component;
 
-import 'package:kernel/text/ast_to_text.dart' show programToString;
+import 'package:kernel/text/ast_to_text.dart' show componentToString;
 
 Future main() async {
   asyncStart();
@@ -31,8 +31,8 @@
     await compare(compiledOnceOutput, compiledTwiceOutput);
     await runCompiler(compiledTwiceOutput, outline, outlineOutput);
     try {
-      // Test that compare actually works by comparing the compile program to
-      // the outline program (which are different, but similar).
+      // Test that compare actually works by comparing the compiled component
+      // to the outline component (which are different, but similar).
       await compare(compiledOnceOutput, outlineOutput, silent: true);
       throw "Expected an error.";
     } on ComparisonFailed {
@@ -78,13 +78,13 @@
   if (!silent) {
     print("$a is different from $b");
   }
-  Program programA = new Program();
-  Program programB = new Program();
-  new BinaryBuilder(bytesA, filename: a.toFilePath()).readProgram(programA);
-  new BinaryBuilder(bytesB, filename: b.toFilePath()).readProgram(programB);
+  Component programA = new Component();
+  Component programB = new Component();
+  new BinaryBuilder(bytesA, filename: a.toFilePath()).readComponent(programA);
+  new BinaryBuilder(bytesB, filename: b.toFilePath()).readComponent(programB);
   RegExp splitLines = new RegExp('^', multiLine: true);
-  List<String> linesA = programToString(programA).split(splitLines);
-  List<String> linesB = programToString(programB).split(splitLines);
+  List<String> linesA = componentToString(programA).split(splitLines);
+  List<String> linesB = componentToString(programB).split(splitLines);
   for (int i = 0; i < linesA.length && i < linesB.length; i++) {
     String lineA = linesA[i].trimRight();
     String lineB = linesB[i].trimRight();
diff --git a/pkg/front_end/test/fasta/incremental_hello_test.dart b/pkg/front_end/test/fasta/incremental_hello_test.dart
index 1b13610..7976f2d 100644
--- a/pkg/front_end/test/fasta/incremental_hello_test.dart
+++ b/pkg/front_end/test/fasta/incremental_hello_test.dart
@@ -8,7 +8,7 @@
 
 import 'package:expect/expect.dart' show Expect;
 
-import 'package:kernel/ast.dart' show Program;
+import 'package:kernel/ast.dart' show Component;
 
 import "package:front_end/src/api_prototype/compiler_options.dart"
     show CompilerOptions;
@@ -55,28 +55,28 @@
   IncrementalCompiler compiler =
       new IncrementalCompiler(new CompilerContext(options));
 
-  Program program = await compiler.computeDelta();
+  Component component = await compiler.computeDelta();
 
   if (sdkFromSource) {
-    // Expect that the new program contains at least the following libraries:
+    // Expect that the new component contains at least the following libraries:
     // dart:core, dart:async, and hello.dart.
     Expect.isTrue(
-        program.libraries.length > 2, "${program.libraries.length} <= 2");
+        component.libraries.length > 2, "${component.libraries.length} <= 2");
   } else {
-    // Expect that the new program contains exactly hello.dart.
+    // Expect that the new component contains exactly hello.dart.
     Expect.isTrue(
-        program.libraries.length == 1, "${program.libraries.length} != 1");
+        component.libraries.length == 1, "${component.libraries.length} != 1");
   }
 
   compiler.invalidate(helloDart);
 
-  program = await compiler.computeDelta(entryPoint: helloDart);
-  // Expect that the new program contains exactly hello.dart
+  component = await compiler.computeDelta(entryPoint: helloDart);
+  // Expect that the new component contains exactly hello.dart
   Expect.isTrue(
-      program.libraries.length == 1, "${program.libraries.length} != 1");
+      component.libraries.length == 1, "${component.libraries.length} != 1");
 
-  program = await compiler.computeDelta(entryPoint: helloDart);
-  Expect.isTrue(program.libraries.isEmpty);
+  component = await compiler.computeDelta(entryPoint: helloDart);
+  Expect.isTrue(component.libraries.isEmpty);
 }
 
 void main() {
diff --git a/pkg/front_end/test/fasta/incremental_test.dart b/pkg/front_end/test/fasta/incremental_test.dart
index d89f3a32..3d2fb2a 100644
--- a/pkg/front_end/test/fasta/incremental_test.dart
+++ b/pkg/front_end/test/fasta/incremental_test.dart
@@ -10,7 +10,7 @@
 
 import "dart:io" show File;
 
-import "package:kernel/ast.dart" show Program;
+import "package:kernel/ast.dart" show Component;
 
 import "package:testing/testing.dart"
     show Chain, ChainContext, Result, Step, TestDescription, runMe;
@@ -146,7 +146,7 @@
         return edits == 0 ? fail(test, "No sources found") : pass(test);
       }
       var compiler = context.compiler;
-      Program program = await compiler.computeDelta(entryPoint: entryPoint);
+      Component component = await compiler.computeDelta(entryPoint: entryPoint);
       List<CompilationMessage> errors = context.takeErrors();
       if (test.expectations[edits].hasCompileTimeError) {
         if (errors.isEmpty) {
@@ -155,7 +155,7 @@
       } else if (errors.isNotEmpty) {
         return fail(
             test, "Unexpected compile-time errors:\n  ${errors.join('\n  ')}");
-      } else if (program.libraries.length < 1) {
+      } else if (component.libraries.length < 1) {
         return fail(test, "The compiler detected no changes");
       }
     }
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index 4efa647..9486a3f 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -331,6 +331,22 @@
     // TOOD(danrubel): dynamic, do, other keywords, malformed, recovery
     // <T>
 
+    expectComplexInfo('G<int double> g',
+        required: true,
+        tokenAfter: 'g',
+        expectedCalls: [
+          'handleIdentifier G typeReference',
+          'beginTypeArguments <',
+          'handleIdentifier int typeReference',
+          'handleNoTypeArguments double',
+          'handleType int double',
+          'endTypeArguments 1 < >',
+          'handleType G double',
+        ],
+        expectedErrors: [
+          error(codeExpectedToken, 6, 6)
+        ]);
+
     expectInfo(noTypeInfo, 'C<>', required: false);
     expectComplexInfo('C<>', required: true, expectedCalls: [
       'handleIdentifier C typeReference',
@@ -340,6 +356,8 @@
       'handleType > >',
       'endTypeArguments 1 < >',
       'handleType C ',
+    ], expectedErrors: [
+      error(codeExpectedType, 2, 1)
     ]);
     expectComplexInfo('C<> f', required: true, tokenAfter: 'f', expectedCalls: [
       'handleIdentifier C typeReference',
@@ -349,6 +367,8 @@
       'handleType > >',
       'endTypeArguments 1 < >',
       'handleType C f',
+    ], expectedErrors: [
+      error(codeExpectedType, 2, 1)
     ]);
 
     // Statements that should not have a type
@@ -528,27 +548,42 @@
 }
 
 void expectInfo(expectedInfo, String source,
-    {bool required, String expectedAfter, List<String> expectedCalls}) {
+    {bool required,
+    String expectedAfter,
+    List<String> expectedCalls,
+    List<ExpectedError> expectedErrors}) {
   Token start = scan(source);
   if (required == null) {
-    compute(expectedInfo, source, start, true, expectedAfter, expectedCalls);
-    compute(expectedInfo, source, start, false, expectedAfter, expectedCalls);
+    compute(expectedInfo, source, start, true, expectedAfter, expectedCalls,
+        expectedErrors);
+    compute(expectedInfo, source, start, false, expectedAfter, expectedCalls,
+        expectedErrors);
   } else {
-    compute(
-        expectedInfo, source, start, required, expectedAfter, expectedCalls);
+    compute(expectedInfo, source, start, required, expectedAfter, expectedCalls,
+        expectedErrors);
   }
 }
 
 void expectComplexInfo(String source,
-    {bool required, String tokenAfter, List<String> expectedCalls}) {
+    {bool required,
+    String tokenAfter,
+    List<String> expectedCalls,
+    List<ExpectedError> expectedErrors}) {
   expectInfo(const isInstanceOf<ComplexTypeInfo>(), source,
       required: required,
       expectedAfter: tokenAfter,
-      expectedCalls: expectedCalls);
+      expectedCalls: expectedCalls,
+      expectedErrors: expectedErrors);
 }
 
-void compute(expectedInfo, String source, Token start, bool required,
-    String expectedAfter, List<String> expectedCalls) {
+void compute(
+    expectedInfo,
+    String source,
+    Token start,
+    bool required,
+    String expectedAfter,
+    List<String> expectedCalls,
+    List<ExpectedError> expectedErrors) {
   TypeInfo typeInfo = computeType(start, required);
   expect(typeInfo, expectedInfo, reason: source);
   if (typeInfo is ComplexTypeInfo) {
@@ -568,6 +603,9 @@
 
       expect(listener.calls, expectedCalls, reason: source);
     }
+    expect(listener.errors, expectedErrors, reason: source);
+  } else {
+    assert(expectedErrors == null);
   }
 }
 
@@ -590,6 +628,7 @@
 
 class TypeInfoListener implements Listener {
   List<String> calls = <String>[];
+  List<ExpectedError> errors;
 
   @override
   void beginFormalParameter(Token token, MemberKind kind) {
@@ -702,7 +741,9 @@
   @override
   void handleRecoverableError(
       Message message, Token startToken, Token endToken) {
-    // ignored
+    errors ??= <ExpectedError>[];
+    int offset = startToken.charOffset;
+    errors.add(error(message.code, offset, endToken.charEnd - offset));
   }
 
   @override
@@ -724,3 +765,24 @@
     throw '${invocation.memberName} should not be called.';
   }
 }
+
+ExpectedError error(Code code, int start, int length) =>
+    new ExpectedError(code, start, length);
+
+class ExpectedError {
+  final Code code;
+  final int start;
+  final int length;
+
+  ExpectedError(this.code, this.start, this.length);
+
+  @override
+  bool operator ==(other) =>
+      other is ExpectedError &&
+      code == other.code &&
+      start == other.start &&
+      length == other.length;
+
+  @override
+  String toString() => 'error(${code.name}, $start, $length)';
+}
diff --git a/pkg/front_end/test/fasta/shaker_test.dart b/pkg/front_end/test/fasta/shaker_test.dart
index 757e778..d86e4d9 100644
--- a/pkg/front_end/test/fasta/shaker_test.dart
+++ b/pkg/front_end/test/fasta/shaker_test.dart
@@ -30,13 +30,13 @@
 import 'package:front_end/src/fasta/kernel/kernel_outline_shaker.dart';
 import 'package:front_end/src/fasta/kernel/kernel_target.dart'
     show KernelTarget;
-import 'package:front_end/src/fasta/kernel/verifier.dart' show verifyProgram;
+import 'package:front_end/src/fasta/kernel/verifier.dart' show verifyComponent;
 import 'package:front_end/src/fasta/testing/kernel_chain.dart'
     show BytesCollector, runDiff;
 import 'package:front_end/src/fasta/util/relativize.dart' show relativizeUri;
-import 'package:kernel/ast.dart' show Program;
+import 'package:kernel/ast.dart' show Component;
 import 'package:kernel/binary/ast_from_binary.dart';
-import 'package:kernel/kernel.dart' show loadProgramFromBytes;
+import 'package:kernel/kernel.dart' show loadComponentFromBytes;
 import 'package:kernel/target/targets.dart' show TargetFlags;
 import 'package:kernel/target/vm.dart' show VmTarget;
 import 'package:kernel/text/ast_to_text.dart';
@@ -70,11 +70,11 @@
           new CheckOutline(updateExpectations: updateExpectations),
         ];
 
-  Program loadPlatformOutline() {
+  Component loadPlatformOutline() {
     // Note: we rebuild the platform outline on every test because the
-    // tree-shaker mutates the in-memory representation of the program without
+    // tree-shaker mutates the in-memory representation of the component without
     // cloning it.
-    return loadProgramFromBytes(outlineBytes);
+    return loadComponentFromBytes(outlineBytes);
   }
 
   static create(Map<String, String> environment) async {
@@ -134,23 +134,23 @@
         var showCoreLibraries = contents.contains("@@SHOW_CORE_LIBRARIES@@");
 
         await sourceTarget.buildOutlines();
-        var program = await sourceTarget.buildProgram();
+        var component = await sourceTarget.buildComponent();
 
         bool isIncluded(Uri uri) => uri == inputUri;
 
-        Program outline;
+        Component outline;
         {
           var bytesCollector = new BytesCollector();
-          serializeTrimmedOutline(bytesCollector, program, isIncluded);
+          serializeTrimmedOutline(bytesCollector, component, isIncluded);
           var bytes = bytesCollector.collect();
-          outline = new Program();
-          new BinaryBuilder(bytes).readProgram(outline);
+          outline = new Component();
+          new BinaryBuilder(bytes).readComponent(outline);
         }
 
-        trimProgram(program, isIncluded);
+        trimProgram(component, isIncluded);
 
         return pass(new _IntermediateData(
-            inputUri, program, outline, showCoreLibraries));
+            inputUri, component, outline, showCoreLibraries));
       } on deprecated_InputError catch (e, s) {
         return fail(null, e.error, s);
       }
@@ -163,11 +163,11 @@
   /// The input URI provided to the test.
   final Uri uri;
 
-  /// Program built by [BuildProgram].
-  final Program program;
+  /// Component built by [BuildProgram].
+  final Component component;
 
-  /// Shaken outline of [program].
-  final Program outline;
+  /// Shaken outline of [component].
+  final Component outline;
 
   /// Whether the output should include tree-shaking information about the core
   /// libraries. This is specified in a comment on individual test files where
@@ -175,7 +175,7 @@
   final bool showCoreLibraries;
 
   _IntermediateData(
-      this.uri, this.program, this.outline, this.showCoreLibraries);
+      this.uri, this.component, this.outline, this.showCoreLibraries);
 }
 
 /// A step that runs the tree-shaker and checks against an expectation file for
@@ -191,9 +191,9 @@
       _IntermediateData data, ChainContext context) async {
     String actualResult;
     var entryUri = data.uri;
-    var program = data.program;
+    var component = data.component;
 
-    var errors = verifyProgram(program, isOutline: false);
+    var errors = verifyComponent(component, isOutline: false);
     if (!errors.isEmpty) {
       return new Result<_IntermediateData>(
           data, context.expectationSet["VerificationError"], errors, null);
@@ -207,7 +207,7 @@
 To update this file, either copy the output from a failing test or run
 pkg/front_end/tool/fasta testing shaker -DupdateExpectations=true''');
 
-    for (var library in program.libraries) {
+    for (var library in component.libraries) {
       var importUri = library.importUri;
       if (importUri == entryUri) continue;
       if (importUri.isScheme('dart') && !data.showCoreLibraries) continue;
@@ -272,7 +272,7 @@
     var entryUri = data.uri;
     var outline = data.outline;
 
-    var errors = verifyProgram(outline, isOutline: true);
+    var errors = verifyComponent(outline, isOutline: true);
     if (!errors.isEmpty) {
       return new Result<String>(
           null, context.expectationSet["VerificationError"], errors, null);
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index d40576b..3337a9e 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -21,7 +21,7 @@
 
 import 'package:front_end/src/fasta/uri_translator_impl.dart';
 
-import 'package:kernel/ast.dart' show Library, Program;
+import 'package:kernel/ast.dart' show Library, Component;
 
 import 'package:testing/testing.dart'
     show
@@ -60,7 +60,7 @@
 
 import 'package:front_end/src/fasta/dill/dill_target.dart' show DillTarget;
 
-import 'package:kernel/kernel.dart' show loadProgramFromBytes;
+import 'package:kernel/kernel.dart' show loadComponentFromBytes;
 
 import 'package:kernel/target/targets.dart' show TargetFlags;
 
@@ -108,11 +108,11 @@
   final Uri vm;
   final bool strongMode;
   final bool onlyCrashes;
-  final Map<Program, KernelTarget> programToTarget = <Program, KernelTarget>{};
+  final Map<Component, KernelTarget> programToTarget =
+      <Component, KernelTarget>{};
   final Uri platformBinaries;
   Uri platformUri;
-  Uri outlineUri;
-  Program outline;
+  Component platform;
 
   final ExpectationSet expectationSet =
       new ExpectationSet.fromJsonList(JSON.decode(EXPECTATIONS));
@@ -150,6 +150,13 @@
       }
       if (fullCompile && !skipVm) {
         steps.add(const Transform());
+        if (!ignoreExpectations) {
+          steps.add(new MatchExpectation(
+              fullCompile
+              ? ".${generateExpectationName(strongMode)}.transformed.expect"
+              : ".outline.transformed.expect",
+              updateExpectations: updateExpectations));
+        }
         steps.add(const WriteDill());
         steps.add(const Run());
       }
@@ -158,19 +165,18 @@
 
   Future ensurePlatformUris() async {
     if (platformUri == null) {
-      platformUri = platformBinaries.resolve("vm_platform.dill");
-      outlineUri = platformBinaries
-          .resolve(strongMode ? "vm_outline_strong.dill" : "vm_outline.dill");
+      platformUri = platformBinaries
+          .resolve(strongMode ? "vm_platform_strong.dill" : "vm_platform.dill");
     }
   }
 
-  Future<Program> loadPlatformOutline() async {
-    if (outline == null) {
+  Future<Component> loadPlatform() async {
+    if (platform == null) {
       await ensurePlatformUris();
-      outline =
-          loadProgramFromBytes(new File.fromUri(outlineUri).readAsBytesSync());
+      platform = loadComponentFromBytes(
+          new File.fromUri(platformUri).readAsBytesSync());
     }
-    return outline;
+    return platform;
   }
 
   @override
@@ -256,7 +262,7 @@
   }
 }
 
-class Outline extends Step<TestDescription, Program, FastaContext> {
+class Outline extends Step<TestDescription, Component, FastaContext> {
   final bool fullCompile;
 
   final AstKind astKind;
@@ -274,18 +280,18 @@
 
   bool get isCompiler => fullCompile;
 
-  Future<Result<Program>> run(
+  Future<Result<Component>> run(
       TestDescription description, FastaContext context) async {
     var options = new ProcessedOptions(new CompilerOptions());
     return await CompilerContext.runWithOptions(options, (_) async {
       // Disable colors to ensure that expectation files are the same across
       // platforms and independent of stdin/stderr.
       CompilerContext.current.disableColors();
-      Program platformOutline = await context.loadPlatformOutline();
+      Component platform = await context.loadPlatform();
       Ticker ticker = new Ticker();
       DillTarget dillTarget = new DillTarget(ticker, context.uriTranslator,
           new TestVmTarget(new TargetFlags(strongMode: strongMode)));
-      dillTarget.loader.appendLibraries(platformOutline);
+      dillTarget.loader.appendLibraries(platform);
       // We create a new URI translator to avoid reading platform libraries from
       // file system.
       UriTranslatorImpl uriTranslator = new UriTranslatorImpl(
@@ -296,7 +302,7 @@
           : new KernelTarget(
               StandardFileSystem.instance, false, dillTarget, uriTranslator);
 
-      Program p;
+      Component p;
       try {
         sourceTarget.read(description.uri);
         await dillTarget.buildOutlines();
@@ -308,7 +314,7 @@
         }
         p = await sourceTarget.buildOutlines();
         if (fullCompile) {
-          p = await sourceTarget.buildProgram();
+          p = await sourceTarget.buildComponent();
           instrumentation?.finish();
           if (instrumentation != null && instrumentation.hasProblems) {
             if (updateComments) {
@@ -328,14 +334,15 @@
   }
 }
 
-class Transform extends Step<Program, Program, FastaContext> {
+class Transform extends Step<Component, Component, FastaContext> {
   const Transform();
 
-  String get name => "transform program";
+  String get name => "transform component";
 
-  Future<Result<Program>> run(Program program, FastaContext context) async {
-    KernelTarget sourceTarget = context.programToTarget[program];
-    context.programToTarget.remove(program);
+  Future<Result<Component>> run(
+      Component component, FastaContext context) async {
+    KernelTarget sourceTarget = context.programToTarget[component];
+    context.programToTarget.remove(component);
     TestVmTarget backendTarget = sourceTarget.backendTarget;
     backendTarget.enabled = true;
     try {
@@ -345,7 +352,7 @@
     } finally {
       backendTarget.enabled = false;
     }
-    return pass(program);
+    return pass(component);
   }
 }
 
@@ -366,10 +373,10 @@
     }
   }
 
-  void performGlobalTransformations(CoreTypes coreTypes, Program program,
+  void performGlobalTransformations(CoreTypes coreTypes, Component component,
       {void logger(String msg)}) {
     if (enabled) {
-      super.performGlobalTransformations(coreTypes, program, logger: logger);
+      super.performGlobalTransformations(coreTypes, component, logger: logger);
     }
   }
 }
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
index 269c4c6..7aca4b1 100644
--- a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
@@ -8,7 +8,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/core_types.dart';
-import 'package:kernel/testing/mock_sdk_program.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';
@@ -23,7 +23,7 @@
 class InterfaceResolverTest {
   final Library testLib;
 
-  final Program program;
+  final Component component;
 
   final CoreTypes coreTypes;
 
@@ -35,14 +35,14 @@
 
   InterfaceResolverTest()
       : this._(new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib'),
-            createMockSdkProgram());
+            createMockSdkComponent());
 
-  InterfaceResolverTest._(this.testLib, Program program)
-      : program = program..libraries.add(testLib..parent = program),
-        coreTypes = new CoreTypes(program);
+  InterfaceResolverTest._(this.testLib, Component component)
+      : component = component..libraries.add(testLib..parent = component),
+        coreTypes = new CoreTypes(component);
 
   ClassHierarchy get classHierarchy {
-    return cachedClassHierarchy ??= new ClassHierarchy(program);
+    return cachedClassHierarchy ??= new ClassHierarchy(component);
   }
 
   TypeSchemaEnvironment get typeEnvironment {
@@ -84,7 +84,7 @@
       expect(interfaceMember, same(member));
     }
 
-    check(new ClassHierarchy(program));
+    check(new ClassHierarchy(component));
   }
 
   Procedure getCandidate(Class class_, bool setter) {
diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
index d51d345..dddce21 100644
--- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
@@ -8,7 +8,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/testing/mock_sdk_program.dart';
+import 'package:kernel/testing/mock_sdk_component.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -29,7 +29,7 @@
   final testLib =
       new Library(Uri.parse('org-dartlang:///test.dart'), name: 'lib');
 
-  Program program;
+  Component component;
 
   CoreTypes coreTypes;
 
@@ -42,9 +42,9 @@
   Class classQ;
 
   TypeConstraintGathererTest() {
-    program = createMockSdkProgram();
-    program.libraries.add(testLib..parent = program);
-    coreTypes = new CoreTypes(program);
+    component = createMockSdkComponent();
+    component.libraries.add(testLib..parent = component);
+    coreTypes = new CoreTypes(component);
     T1 = new TypeParameterType(new TypeParameter('T1', objectType));
     T2 = new TypeParameterType(new TypeParameter('T2', objectType));
     classP = _addClass(_class('P'));
@@ -209,8 +209,8 @@
 
   void _checkConstraints(
       DartType a, DartType b, List<String> expectedConstraints) {
-    var typeSchemaEnvironment =
-        new TypeSchemaEnvironment(coreTypes, new ClassHierarchy(program), true);
+    var typeSchemaEnvironment = new TypeSchemaEnvironment(
+        coreTypes, new ClassHierarchy(component), true);
     var typeConstraintGatherer = new TypeConstraintGatherer(
         typeSchemaEnvironment, [T1.parameter, T2.parameter]);
     var constraints = typeConstraintGatherer.trySubtypeMatch(a, b)
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
index a8335b2..4621b9a 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
@@ -7,7 +7,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/testing/mock_sdk_program.dart';
+import 'package:kernel/testing/mock_sdk_component.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -29,14 +29,14 @@
 
   final testLib = new Library(Uri.parse('org-dartlang:///test.dart'));
 
-  Program program;
+  Component component;
 
   CoreTypes coreTypes;
 
   TypeSchemaEnvironmentTest() {
-    program = createMockSdkProgram();
-    program.libraries.add(testLib..parent = program);
-    coreTypes = new CoreTypes(program);
+    component = createMockSdkComponent();
+    component.libraries.add(testLib..parent = component);
+    coreTypes = new CoreTypes(component);
   }
 
   InterfaceType get doubleType => coreTypes.doubleClass.rawType;
@@ -714,7 +714,7 @@
 
   TypeSchemaEnvironment _makeEnv() {
     return new TypeSchemaEnvironment(
-        coreTypes, new ClassHierarchy(program), true);
+        coreTypes, new ClassHierarchy(component), true);
   }
 
   DartType _map(DartType key, DartType value) =>
diff --git a/pkg/front_end/test/incremental_load_from_dill_test.dart b/pkg/front_end/test/incremental_load_from_dill_test.dart
index 686cda7..13ab958 100644
--- a/pkg/front_end/test/incremental_load_from_dill_test.dart
+++ b/pkg/front_end/test/incremental_load_from_dill_test.dart
@@ -15,11 +15,11 @@
 import 'package:front_end/src/fasta/incremental_compiler.dart'
     show IncrementalCompiler;
 import 'package:front_end/src/fasta/kernel/utils.dart'
-    show writeProgramToFile, serializeProgram;
+    show writeComponentToFile, serializeComponent;
 import "package:front_end/src/api_prototype/memory_file_system.dart"
     show MemoryFileSystem;
 import 'package:kernel/kernel.dart'
-    show Class, EmptyStatement, Library, Procedure, Program;
+    show Class, EmptyStatement, Library, Procedure, Component;
 
 import 'package:front_end/src/fasta/fasta_codes.dart' show LocatedMessage;
 
@@ -366,16 +366,16 @@
     IncrementalCompiler compiler =
         new IncrementalKernelGenerator(options, main);
     Stopwatch stopwatch = new Stopwatch()..start();
-    var program = await compiler.computeDelta();
-    throwOnEmptyMixinBodies(program);
+    var component = await compiler.computeDelta();
+    throwOnEmptyMixinBodies(component);
     print("Normal compile took ${stopwatch.elapsedMilliseconds} ms");
-    libCount2 = serializeProgram(program);
-    if (program.libraries.length != 2) {
-      throw "Expected 2 libraries, got ${program.libraries.length}";
+    libCount2 = serializeComponent(component);
+    if (component.libraries.length != 2) {
+      throw "Expected 2 libraries, got ${component.libraries.length}";
     }
-    if (program.libraries[0].fileUri != main) {
+    if (component.libraries[0].fileUri != main) {
       throw "Expected the first library to have uri $main but was "
-          "${program.libraries[0].fileUri}";
+          "${component.libraries[0].fileUri}";
     }
   }
 
@@ -399,11 +399,11 @@
     compiler.invalidate(main);
     compiler.invalidate(b);
     Stopwatch stopwatch = new Stopwatch()..start();
-    var program = await compiler.computeDelta();
-    throwOnEmptyMixinBodies(program);
+    var component = await compiler.computeDelta();
+    throwOnEmptyMixinBodies(component);
     print("Bootstrapped compile took ${stopwatch.elapsedMilliseconds} ms");
-    if (program.libraries.length != 1) {
-      throw "Expected 1 library, got ${program.libraries.length}";
+    if (component.libraries.length != 1) {
+      throw "Expected 1 library, got ${component.libraries.length}";
     }
   }
 }
@@ -434,22 +434,22 @@
     {CompilerOptions options}) async {
   options ??= getOptions(false);
   IncrementalCompiler compiler = new IncrementalKernelGenerator(options, input);
-  var program = await compiler.computeDelta();
-  throwOnEmptyMixinBodies(program);
-  await writeProgramToFile(program, output);
+  var component = await compiler.computeDelta();
+  throwOnEmptyMixinBodies(component);
+  await writeComponentToFile(component, output);
   return compiler.initializedFromDill;
 }
 
-void throwOnEmptyMixinBodies(Program program) {
-  int empty = countEmptyMixinBodies(program);
+void throwOnEmptyMixinBodies(Component component) {
+  int empty = countEmptyMixinBodies(component);
   if (empty != 0) {
     throw "Expected 0 empty bodies in mixins, but found $empty";
   }
 }
 
-int countEmptyMixinBodies(Program program) {
+int countEmptyMixinBodies(Component component) {
   int empty = 0;
-  for (Library lib in program.libraries) {
+  for (Library lib in component.libraries) {
     for (Class c in lib.classes) {
       if (c.isSyntheticMixinImplementation) {
         // Assume mixin
@@ -476,7 +476,7 @@
   var bootstrappedProgram = await compiler.computeDelta();
   throwOnEmptyMixinBodies(bootstrappedProgram);
   bool result = compiler.initializedFromDill;
-  await writeProgramToFile(bootstrappedProgram, output);
+  await writeComponentToFile(bootstrappedProgram, output);
   for (Uri invalidateUri in invalidateUris) {
     compiler.invalidate(invalidateUri);
   }
diff --git a/pkg/front_end/test/kernel_generator_test.dart b/pkg/front_end/test/kernel_generator_test.dart
index f84b832..6a2c923 100644
--- a/pkg/front_end/test/kernel_generator_test.dart
+++ b/pkg/front_end/test/kernel_generator_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart'
-    show EmptyStatement, Program, ReturnStatement, StaticInvocation;
+    show EmptyStatement, Component, ReturnStatement, StaticInvocation;
 
 import 'package:test/test.dart'
     show
@@ -28,7 +28,7 @@
 
 import 'package:front_end/src/fasta/fasta_codes.dart' show messageMissingMain;
 
-import 'package:front_end/src/fasta/kernel/utils.dart' show serializeProgram;
+import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
 
 import 'package:front_end/src/testing/compiler_common.dart'
     show
@@ -48,9 +48,9 @@
         ..compileSdk = true // To prevent FE from loading an sdk-summary.
         ..onError = (e) => errors.add(e);
 
-      var program =
+      var component =
           await compileScript('main() => print("hi");', options: options);
-      expect(program, isNull);
+      expect(component, isNull);
       expect(errors, isNotEmpty);
     });
 
@@ -61,22 +61,22 @@
             Uri.parse('org-dartlang-test:///not_existing_summary_file')
         ..onError = (e) => errors.add(e);
 
-      var program =
+      var component =
           await compileScript('main() => print("hi");', options: options);
-      expect(program, isNull);
+      expect(component, isNull);
       expect(errors, isNotEmpty);
     });
 
-    test('by default program is compiled using the full platform file',
+    test('by default component is compiled using the full platform file',
         () async {
       var options = new CompilerOptions()
         // Note: we define [librariesSpecificationUri] with a specification that
         // contains broken URIs to ensure we do not attempt to lookup for
         // sources of the sdk directly.
         ..librariesSpecificationUri = invalidCoreLibsSpecUri;
-      var program =
+      var component =
           await compileScript('main() => print("hi");', options: options);
-      var core = program.libraries.firstWhere(isDartCoreLibrary);
+      var core = component.libraries.firstWhere(isDartCoreLibrary);
       var printMember = core.members.firstWhere((m) => m.name.name == 'print');
 
       // Note: summaries created by the SDK today contain empty statements as
@@ -107,29 +107,29 @@
       expect(exceptionThrown, isTrue);
     }, skip: true /* Issue 30194 */);
 
-    test('generated program contains source-info', () async {
-      var program = await compileScript('a() => print("hi"); main() {}',
+    test('generated component contains source-info', () async {
+      var component = await compileScript('a() => print("hi"); main() {}',
           fileName: 'a.dart');
       // Kernel always store an empty '' key in the map, so there is always at
       // least one. Having more means that source-info is added.
-      expect(program.uriToSource.keys.length, greaterThan(1));
+      expect(component.uriToSource.keys.length, greaterThan(1));
       expect(
-          program.uriToSource[Uri.parse('org-dartlang-test:///a/b/c/a.dart')],
+          component.uriToSource[Uri.parse('org-dartlang-test:///a/b/c/a.dart')],
           isNotNull);
     });
 
     test('code from summary dependencies are marked external', () async {
-      var program = await compileScript('a() => print("hi"); main() {}',
+      var component = await compileScript('a() => print("hi"); main() {}',
           fileName: 'a.dart');
-      for (var lib in program.libraries) {
+      for (var lib in component.libraries) {
         if (lib.importUri.scheme == 'dart') {
           expect(lib.isExternal, isTrue);
         }
       }
 
       // Pretend that the compiled code is a summary
-      var bytes = serializeProgram(program);
-      program = await compileScript(
+      var bytes = serializeComponent(component);
+      component = await compileScript(
           {
             'b.dart': 'import "a.dart" as m; b() => m.a(); main() {}',
             'summary.dill': bytes
@@ -137,22 +137,22 @@
           fileName: 'b.dart',
           inputSummaries: ['summary.dill']);
 
-      var aLib = program.libraries
+      var aLib = component.libraries
           .firstWhere((lib) => lib.importUri.path == '/a/b/c/a.dart');
       expect(aLib.isExternal, isTrue);
     });
 
     test('code from linked dependencies are not marked external', () async {
-      var program = await compileScript('a() => print("hi"); main() {}',
+      var component = await compileScript('a() => print("hi"); main() {}',
           fileName: 'a.dart');
-      for (var lib in program.libraries) {
+      for (var lib in component.libraries) {
         if (lib.importUri.scheme == 'dart') {
           expect(lib.isExternal, isTrue);
         }
       }
 
-      var bytes = serializeProgram(program);
-      program = await compileScript(
+      var bytes = serializeComponent(component);
+      component = await compileScript(
           {
             'b.dart': 'import "a.dart" as m; b() => m.a(); main() {}',
             'link.dill': bytes
@@ -160,7 +160,7 @@
           fileName: 'b.dart',
           linkedDependencies: ['link.dill']);
 
-      var aLib = program.libraries
+      var aLib = component.libraries
           .firstWhere((lib) => lib.importUri.path == '/a/b/c/a.dart');
       expect(aLib.isExternal, isFalse);
     });
@@ -168,7 +168,7 @@
     // TODO(sigmund): add tests discovering libraries.json
   });
 
-  group('kernelForBuildUnit', () {
+  group('kernelForComponent', () {
     test('compiler does not require a main method', () async {
       var errors = [];
       var options = new CompilerOptions()..onError = (e) => errors.add(e);
@@ -216,17 +216,17 @@
 
       var unitA = await compileUnit(['a.dart'], sources);
       // Pretend that the compiled code is a summary
-      sources['a.dill'] = serializeProgram(unitA);
+      sources['a.dill'] = serializeComponent(unitA);
 
       var unitBC = await compileUnit(['b.dart', 'c.dart'], sources,
           inputSummaries: ['a.dill']);
 
       // Pretend that the compiled code is a summary
-      sources['bc.dill'] = serializeProgram(unitBC);
+      sources['bc.dill'] = serializeComponent(unitBC);
 
-      void checkDCallsC(Program program) {
-        var dLib = findLibrary(program, 'd.dart');
-        var cLib = findLibrary(program, 'c.dart');
+      void checkDCallsC(Component component) {
+        var dLib = findLibrary(component, 'd.dart');
+        var cLib = findLibrary(component, 'c.dart');
         var dMethod = dLib.procedures.first;
         var dBody = dMethod.function.body;
         var dCall = (dBody as ReturnStatement).expression;
diff --git a/pkg/front_end/test/src/base/processed_options_test.dart b/pkg/front_end/test/src/base/processed_options_test.dart
index 359acab..2ce4498 100644
--- a/pkg/front_end/test/src/base/processed_options_test.dart
+++ b/pkg/front_end/test/src/base/processed_options_test.dart
@@ -12,7 +12,7 @@
 import 'package:front_end/src/fasta/fasta_codes.dart';
 import 'package:kernel/binary/ast_to_binary.dart' show BinaryPrinter;
 import 'package:kernel/kernel.dart'
-    show CanonicalName, Library, Program, loadProgramFromBytes;
+    show CanonicalName, Library, Component, loadComponentFromBytes;
 import 'package:package_config/packages.dart' show Packages;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -30,9 +30,9 @@
   MemoryFileSystem fileSystem =
       new MemoryFileSystem(Uri.parse('org-dartlang-test:///'));
 
-  Program _mockOutline;
+  Component _mockOutline;
 
-  Program get mockSummary => _mockOutline ??= new Program(
+  Component get mockSummary => _mockOutline ??= new Component(
       libraries: [new Library(Uri.parse('org-dartlang-test:///a/b.dart'))]);
 
   test_compileSdk_false() {
@@ -80,7 +80,7 @@
     var bytes = await processed.loadSdkSummaryBytes();
     expect(bytes, isNotEmpty);
 
-    var sdkSummary = loadProgramFromBytes(bytes);
+    var sdkSummary = loadComponentFromBytes(bytes);
     expect(sdkSummary.libraries.single.importUri,
         mockSummary.libraries.single.importUri);
   }
@@ -95,7 +95,7 @@
 
   void writeMockSummaryTo(Uri uri) {
     var sink = new BytesSink();
-    new BinaryPrinter(sink).writeProgramFile(mockSummary);
+    new BinaryPrinter(sink).writeComponentFile(mockSummary);
     fileSystem.entityForUri(uri).writeAsBytesSync(sink.builder.takeBytes());
   }
 
diff --git a/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart b/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
index 23e91a3..56728d6 100644
--- a/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
+++ b/pkg/front_end/test/src/incremental/hot_reload_e2e_test.dart
@@ -17,7 +17,7 @@
 
 import 'package:expect/expect.dart' show Expect;
 
-import 'package:kernel/ast.dart' show Program;
+import 'package:kernel/ast.dart' show Component;
 
 import 'package:kernel/binary/limited_ast_to_binary.dart'
     show LimitedBinaryPrinter;
@@ -308,21 +308,21 @@
   compiler.invalidate(Uri.parse("org-dartlang-test:///a.dart"));
   compiler.invalidate(Uri.parse("org-dartlang-test:///b.dart"));
   compiler.invalidate(Uri.parse("org-dartlang-test:///c.dart"));
-  var program = await compiler.computeDelta();
-  if (program != null && !program.libraries.isEmpty) {
-    await writeProgram(program, outputUri);
+  var component = await compiler.computeDelta();
+  if (component != null && !component.libraries.isEmpty) {
+    await writeProgram(component, outputUri);
     return true;
   }
   return false;
 }
 
-Future<Null> writeProgram(Program program, Uri outputUri) async {
+Future<Null> writeProgram(Component component, Uri outputUri) async {
   var sink = new File.fromUri(outputUri).openWrite();
   // TODO(sigmund): the incremental generator should always filter these
   // libraries instead.
   new LimitedBinaryPrinter(
           sink, (library) => library.importUri.scheme != 'dart', false)
-      .writeProgramFile(program);
+      .writeComponentFile(component);
   await sink.close();
 }
 
diff --git a/pkg/front_end/test/src/incremental/kernel_driver_test.dart b/pkg/front_end/test/src/incremental/kernel_driver_test.dart
index 28554bd..febded4 100644
--- a/pkg/front_end/test/src/incremental/kernel_driver_test.dart
+++ b/pkg/front_end/test/src/incremental/kernel_driver_test.dart
@@ -567,9 +567,9 @@
           'dart.async::Future<dart.core::String>');
 
       // We should be able to serialize the libraries without SDK.
-      var program =
-          new Program(nameRoot: kernelResult.nameRoot, libraries: allLibraries);
-      serializeProgram(program,
+      var component = new Component(
+          nameRoot: kernelResult.nameRoot, libraries: allLibraries);
+      serializeComponent(component,
           filter: (library) => !library.importUri.isScheme('dart'));
     }
 
@@ -710,43 +710,43 @@
 
     KernelSequenceResult result = await driver.getKernelSequence(bUri);
 
-    Program program = new Program(
+    Component component = new Component(
         nameRoot: result.nameRoot, libraries: _allLibraries(result));
 
     String initialKernelText;
     List<int> bytes;
     {
-      Library initialLibrary = _getLibraryFromProgram(program, bUri);
+      Library initialLibrary = _getLibraryFromProgram(component, bUri);
       initialKernelText = _getLibraryText(initialLibrary);
 
-      bytes = serializeProgram(program,
+      bytes = serializeComponent(component,
           filter: (library) => library.importUri == bUri);
 
-      // Remove b.dart from the program.
-      // So, the program is now ready for re-adding the library.
-      program.mainMethod = null;
-      program.libraries.remove(initialLibrary);
-      program.root.removeChild(initialLibrary.importUri.toString());
+      // Remove b.dart from the component.
+      // So, the component is now ready for re-adding the library.
+      component.mainMethod = null;
+      component.libraries.remove(initialLibrary);
+      component.root.removeChild(initialLibrary.importUri.toString());
     }
 
     // Load b.dart from bytes using the initial name root, so that
     // serialized canonical names can be linked to corresponding nodes.
     Library loadedLibrary;
     {
-      var programForLoading = new Program(nameRoot: program.root);
+      var programForLoading = new Component(nameRoot: component.root);
       var reader = new BinaryBuilder(bytes);
-      reader.readProgram(programForLoading);
+      reader.readComponent(programForLoading);
       loadedLibrary = _getLibraryFromProgram(programForLoading, bUri);
     }
 
-    // Add the library into the program.
-    program.libraries.add(loadedLibrary);
-    loadedLibrary.parent = program;
-    program.mainMethod = loadedLibrary.procedures
+    // Add the library into the component.
+    component.libraries.add(loadedLibrary);
+    loadedLibrary.parent = component;
+    component.mainMethod = loadedLibrary.procedures
         .firstWhere((procedure) => procedure.name.name == 'main');
 
     expect(_getLibraryText(loadedLibrary), initialKernelText);
-    verifyProgram(program);
+    verifyComponent(component);
   }
 
   test_updatePackageSourceUsingFileUri() async {
@@ -1023,8 +1023,8 @@
     fail('No library found with URI "$uri"');
   }
 
-  Library _getLibraryFromProgram(Program program, Uri uri) {
-    for (var library in program.libraries) {
+  Library _getLibraryFromProgram(Component component, Uri uri) {
+    for (var library in component.libraries) {
       if (library.importUri == uri) return library;
     }
     fail('No library found with URI "$uri"');
diff --git a/pkg/front_end/test/summary_generator_test.dart b/pkg/front_end/test/summary_generator_test.dart
index 36306a2..05d582c 100644
--- a/pkg/front_end/test/summary_generator_test.dart
+++ b/pkg/front_end/test/summary_generator_test.dart
@@ -12,17 +12,17 @@
 main() {
   test('summary has no source-info by default', () async {
     var summary = await summarize(['a.dart'], allSources);
-    var program = loadProgramFromBytes(summary);
+    var component = loadComponentFromBytes(summary);
 
     // Note: the kernel representation always has an empty '' key in the map,
     // but otherwise no other data is included here.
-    expect(program.uriToSource.keys.single, Uri.parse(""));
+    expect(component.uriToSource.keys.single, Uri.parse(""));
   });
 
   test('summary includes declarations, but no method bodies', () async {
     var summary = await summarize(['a.dart'], allSources);
-    var program = loadProgramFromBytes(summary);
-    var aLib = findLibrary(program, 'a.dart');
+    var component = loadComponentFromBytes(summary);
+    var aLib = findLibrary(component, 'a.dart');
     expect(aLib.importUri.path, '/a/b/c/a.dart');
     var classA = aLib.classes.first;
     expect(classA.name, 'A');
@@ -33,8 +33,8 @@
 
   test('summarized libraries are not marked external', () async {
     var summary = await summarize(['a.dart'], allSources);
-    var program = loadProgramFromBytes(summary);
-    var aLib = findLibrary(program, 'a.dart');
+    var component = loadComponentFromBytes(summary);
+    var aLib = findLibrary(component, 'a.dart');
     expect(aLib.importUri.path, '/a/b/c/a.dart');
     expect(aLib.isExternal, isFalse);
   });
@@ -42,8 +42,8 @@
   test('sdk dependencies are marked external', () async {
     // Note: by default this test is loading the SDK from summaries.
     var summary = await summarize(['a.dart'], allSources);
-    var program = loadProgramFromBytes(summary);
-    var coreLib = findLibrary(program, 'core');
+    var component = loadComponentFromBytes(summary);
+    var coreLib = findLibrary(component, 'core');
     expect(coreLib.isExternal, isTrue);
   });
 
@@ -54,9 +54,9 @@
     var summaryB =
         await summarize(['b.dart'], sourcesWithA, inputSummaries: ['a.dill']);
 
-    var program = loadProgramFromBytes(summaryB);
-    var aLib = findLibrary(program, 'a.dart');
-    var bLib = findLibrary(program, 'b.dart');
+    var component = loadComponentFromBytes(summaryB);
+    var aLib = findLibrary(component, 'a.dart');
+    var bLib = findLibrary(component, 'b.dart');
     expect(aLib.isExternal, isTrue);
     expect(bLib.isExternal, isFalse);
   });
@@ -103,17 +103,19 @@
   test('dependencies not included in truncated summaries', () async {
     // Note: by default this test is loading the SDK from summaries.
     var summaryA = await summarize(['a.dart'], allSources, truncate: true);
-    var program = loadProgramFromBytes(summaryA);
-    expect(program.libraries.length, 1);
-    expect(program.libraries.single.importUri.path.endsWith('a.dart'), isTrue);
+    var component = loadComponentFromBytes(summaryA);
+    expect(component.libraries.length, 1);
+    expect(
+        component.libraries.single.importUri.path.endsWith('a.dart'), isTrue);
 
     var sourcesWithA = new Map.from(allSources);
     sourcesWithA['a.dill'] = summaryA;
     var summaryB = await summarize(['b.dart'], sourcesWithA,
         inputSummaries: ['a.dill'], truncate: true);
-    program = loadProgramFromBytes(summaryB);
-    expect(program.libraries.length, 1);
-    expect(program.libraries.single.importUri.path.endsWith('b.dart'), isTrue);
+    component = loadComponentFromBytes(summaryB);
+    expect(component.libraries.length, 1);
+    expect(
+        component.libraries.single.importUri.path.endsWith('b.dart'), isTrue);
   });
 
   test('summarization by default is hermetic', () async {
@@ -143,11 +145,11 @@
 
 /// Helper function to check that some expectations from the summary of D.
 checkDSummary(List<int> summary) {
-  var program = loadProgramFromBytes(summary);
-  var aLib = findLibrary(program, 'a.dart');
-  var bLib = findLibrary(program, 'b.dart');
-  var cLib = findLibrary(program, 'c.dart');
-  var dLib = findLibrary(program, 'd.dart');
+  var component = loadComponentFromBytes(summary);
+  var aLib = findLibrary(component, 'a.dart');
+  var bLib = findLibrary(component, 'b.dart');
+  var cLib = findLibrary(component, 'c.dart');
+  var dLib = findLibrary(component, 'd.dart');
 
   // All libraries but `d.dart` are marked external.
   expect(aLib.isExternal, isTrue);
diff --git a/pkg/front_end/testcases/accessors.dart.direct.transformed.expect b/pkg/front_end/testcases/accessors.dart.direct.transformed.expect
new file mode 100644
index 0000000..342baaf
--- /dev/null
+++ b/pkg/front_end/testcases/accessors.dart.direct.transformed.expect
@@ -0,0 +1,51 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set onlySetter(dynamic value) → void {
+    core::print("C.onlySetter called with ${value}.");
+  }
+  method testC() → dynamic {
+    try {
+      core::print(this.onlySetter);
+      throw "No error thrown";
+    }
+    on core::NoSuchMethodError catch(final core::NoSuchMethodError e) {
+      core::print("Expected error: ${e}");
+    }
+    this.{self::C::onlySetter} = "hest";
+  }
+  method testD() → dynamic {
+    core::print(this.onlySetter);
+    this.{self::C::onlySetter} = "hest";
+  }
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  get onlySetter() → core::String
+    return "D.onlySetter called.";
+  set onlySetter(dynamic value) → void {
+    core::print("D.onlySetter called with ${value}.");
+  }
+}
+static set onlySetter(dynamic value) → void {
+  core::print("onlySetter called with ${value}.");
+}
+static method main() → dynamic {
+  try {
+    core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#onlySetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    throw "No error thrown";
+  }
+  on core::NoSuchMethodError catch(final core::NoSuchMethodError e) {
+    core::print("Expected error: ${e}");
+  }
+  self::onlySetter = "fisk";
+  new self::C::•().testC();
+  new self::D::•().testD();
+}
diff --git a/pkg/front_end/testcases/ambiguous_exports.dart.direct.transformed.expect b/pkg/front_end/testcases/ambiguous_exports.dart.direct.transformed.expect
new file mode 100644
index 0000000..b45d2fc
--- /dev/null
+++ b/pkg/front_end/testcases/ambiguous_exports.dart.direct.transformed.expect
@@ -0,0 +1,4 @@
+library;
+import self as self;
+
+static const field dynamic _exports# = "{\"main\":\"'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.\"}" /* from null */;
diff --git a/pkg/front_end/testcases/ambiguous_exports.dart.strong.transformed.expect b/pkg/front_end/testcases/ambiguous_exports.dart.strong.transformed.expect
new file mode 100644
index 0000000..b45d2fc
--- /dev/null
+++ b/pkg/front_end/testcases/ambiguous_exports.dart.strong.transformed.expect
@@ -0,0 +1,4 @@
+library;
+import self as self;
+
+static const field dynamic _exports# = "{\"main\":\"'main' is exported from both 'pkg/front_end/testcases/hello.dart' and 'pkg/front_end/testcases/map.dart'.\"}" /* from null */;
diff --git a/pkg/front_end/testcases/annotation_eof.dart.direct.transformed.expect b/pkg/front_end/testcases/annotation_eof.dart.direct.transformed.expect
new file mode 100644
index 0000000..62142d7
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_eof.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''."]/* from null */;
+static method main() → dynamic {
+  core::print("There is a dangling annotation at the end of this file");
+}
diff --git a/pkg/front_end/testcases/annotation_eof.dart.strong.transformed.expect b/pkg/front_end/testcases/annotation_eof.dart.strong.transformed.expect
new file mode 100644
index 0000000..62142d7
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_eof.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/annotation_eof.dart:10:1: Error: Expected a declaration, but got ''."]/* from null */;
+static method main() → dynamic {
+  core::print("There is a dangling annotation at the end of this file");
+}
diff --git a/pkg/front_end/testcases/annotation_top.dart.direct.transformed.expect b/pkg/front_end/testcases/annotation_top.dart.direct.transformed.expect
new file mode 100644
index 0000000..69d3ebe
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_top.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+@test::a
+@test::A::•(1)
+library test;
+import self as self;
+import "dart:core" as core;
+
+@self::a
+@self::A::•(2)
+typedef F1 = () → void;
+@self::a
+@self::A::•(3)
+typedef F2 = () → void;
+class A extends core::Object {
+  const constructor •(core::int value) → void
+    : super core::Object::•()
+    ;
+}
+@self::a
+@self::A::•(2)
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field core::Object a = const core::Object::•();
+@self::a
+@self::A::•(3)
+static field core::int f1;
+@self::a
+@self::A::•(3)
+static field core::int f2;
+@self::a
+@self::A::•(4)
+static method main() → void {}
diff --git a/pkg/front_end/testcases/annotation_top.dart.strong.transformed.expect b/pkg/front_end/testcases/annotation_top.dart.strong.transformed.expect
new file mode 100644
index 0000000..69d3ebe
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_top.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+@test::a
+@test::A::•(1)
+library test;
+import self as self;
+import "dart:core" as core;
+
+@self::a
+@self::A::•(2)
+typedef F1 = () → void;
+@self::a
+@self::A::•(3)
+typedef F2 = () → void;
+class A extends core::Object {
+  const constructor •(core::int value) → void
+    : super core::Object::•()
+    ;
+}
+@self::a
+@self::A::•(2)
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field core::Object a = const core::Object::•();
+@self::a
+@self::A::•(3)
+static field core::int f1;
+@self::a
+@self::A::•(3)
+static field core::int f2;
+@self::a
+@self::A::•(4)
+static method main() → void {}
diff --git a/pkg/front_end/testcases/argument.dart.direct.transformed.expect b/pkg/front_end/testcases/argument.dart.direct.transformed.expect
new file mode 100644
index 0000000..3eb116b
--- /dev/null
+++ b/pkg/front_end/testcases/argument.dart.direct.transformed.expect
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class Base extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Foo extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Bar extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Baz extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method foo(dynamic x) → void {}
+static method bar(dynamic x) → void {}
+static method foo_escaped(dynamic x) → void {}
+static method bar_escaped(dynamic x) → void {}
+static method escape(dynamic fn) → void {
+  fn.call(new self::Baz::•());
+}
+static method main() → dynamic {
+  self::foo(new self::Foo::•());
+  self::bar(new self::Bar::•());
+  self::escape(self::foo_escaped);
+  self::escape(self::bar_escaped);
+}
diff --git a/pkg/front_end/testcases/argument.dart.strong.transformed.expect b/pkg/front_end/testcases/argument.dart.strong.transformed.expect
new file mode 100644
index 0000000..3eb116b
--- /dev/null
+++ b/pkg/front_end/testcases/argument.dart.strong.transformed.expect
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class Base extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Foo extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Bar extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Baz extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method foo(dynamic x) → void {}
+static method bar(dynamic x) → void {}
+static method foo_escaped(dynamic x) → void {}
+static method bar_escaped(dynamic x) → void {}
+static method escape(dynamic fn) → void {
+  fn.call(new self::Baz::•());
+}
+static method main() → dynamic {
+  self::foo(new self::Foo::•());
+  self::bar(new self::Bar::•());
+  self::escape(self::foo_escaped);
+  self::escape(self::bar_escaped);
+}
diff --git a/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect b/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect
new file mode 100644
index 0000000..5d084af
--- /dev/null
+++ b/pkg/front_end/testcases/argument_mismatch.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo() → dynamic {}
+static method test() → dynamic {
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[null].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/arithmetic.dart.direct.transformed.expect b/pkg/front_end/testcases/arithmetic.dart.direct.transformed.expect
new file mode 100644
index 0000000..7c867f3
--- /dev/null
+++ b/pkg/front_end/testcases/arithmetic.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo(core::int x, core::int y) → core::int {
+  dynamic z = x.+(y);
+  return z.<<(4);
+}
+static method loop(core::List<dynamic> xs) → void {
+  core::int _ = xs.length;
+  for (core::int i = 0; i.<(xs.length); i = i.+(1)) {
+  }
+}
+static method main() → dynamic {
+  self::foo(4, 5);
+  self::foo(6, 7);
+  self::loop(<dynamic>["dfg"]);
+}
diff --git a/pkg/front_end/testcases/arithmetic.dart.strong.transformed.expect b/pkg/front_end/testcases/arithmetic.dart.strong.transformed.expect
new file mode 100644
index 0000000..0eac1ce
--- /dev/null
+++ b/pkg/front_end/testcases/arithmetic.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo(core::int x, core::int y) → core::int {
+  core::int z = x.{core::num::+}(y);
+  return z.{core::int::<<}(4);
+}
+static method loop(core::List<dynamic> xs) → void {
+  core::int _ = xs.{core::List::length};
+  for (core::int i = 0; i.{core::num::<}(xs.{core::List::length}); i = i.{core::num::+}(1)) {
+  }
+}
+static method main() → dynamic {
+  self::foo(4, 5);
+  self::foo(6, 7);
+  self::loop(<dynamic>["dfg"]);
+}
diff --git a/pkg/front_end/testcases/arrow_function.dart.direct.transformed.expect b/pkg/front_end/testcases/arrow_function.dart.direct.transformed.expect
new file mode 100644
index 0000000..ec2e898
--- /dev/null
+++ b/pkg/front_end/testcases/arrow_function.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main<T extends core::Object>() → dynamic
+  return () → dynamic => self::main::T;
diff --git a/pkg/front_end/testcases/arrow_function.dart.strong.transformed.expect b/pkg/front_end/testcases/arrow_function.dart.strong.transformed.expect
new file mode 100644
index 0000000..4cea2f2
--- /dev/null
+++ b/pkg/front_end/testcases/arrow_function.dart.strong.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main<T extends core::Object>() → dynamic
+  return () → core::Type => self::main::T;
diff --git a/pkg/front_end/testcases/async_function.dart.direct.transformed.expect b/pkg/front_end/testcases/async_function.dart.direct.transformed.expect
new file mode 100644
index 0000000..6d5759c
--- /dev/null
+++ b/pkg/front_end/testcases/async_function.dart.direct.transformed.expect
@@ -0,0 +1,199 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static field core::List<core::String> stringList = <dynamic>["bar"];
+static method asyncString() → asy::Future<core::String> /* originally async */ {
+  final asy::Completer<core::String> :completer = asy::Completer::sync<core::String>();
+  asy::FutureOr<core::String> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = "foo";
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method asyncString2() → asy::Future<core::String> /* originally async */ {
+  final asy::Completer<core::String> :completer = asy::Completer::sync<core::String>();
+  asy::FutureOr<core::String> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = self::asyncString();
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method syncStarString() → core::Iterable<core::String> /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::String> :iterator) → core::bool yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = "foo";
+        [yield] true;
+      }
+      {
+        :iterator.{core::_SyncIterator::_yieldEachIterable} = self::syncStarString2();
+        [yield] true;
+      }
+      {
+        :iterator.{core::_SyncIterator::_yieldEachIterable} = self::stringList;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::String>(:sync_op);
+}
+static method syncStarString2() → core::Iterable<core::String> /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::String> :iterator) → core::bool yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = "foo";
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::String>(:sync_op);
+}
+static method asyncStarString() → asy::Stream<core::String> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::String> :controller;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L3:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}("foo"))
+            return null;
+          else
+            [yield] null;
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(self::asyncStarString2()))
+            return null;
+          else
+            [yield] null;
+          [yield] let dynamic #t1 = asy::_awaitHelper(self::asyncString(), :async_op_then, :async_op_error, :async_op) in null;
+          if(:controller.{asy::_AsyncStarStreamController::add}(:result))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::String>(:async_op);
+  return :controller.{asy::_AsyncStarStreamController::stream};
+}
+static method asyncStarString2() → asy::Stream<core::String> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::String> :controller;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L4:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}("bar"))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::String>(:async_op);
+  return :controller.{asy::_AsyncStarStreamController::stream};
+}
+static method main() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L5:
+      {
+        [yield] let dynamic #t2 = asy::_awaitHelper(self::asyncString(), :async_op_then, :async_op_error, :async_op) in null;
+        core::String str = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/await.dart.direct.transformed.expect b/pkg/front_end/testcases/await.dart.direct.transformed.expect
new file mode 100644
index 0000000..7a12084
--- /dev/null
+++ b/pkg/front_end/testcases/await.dart.direct.transformed.expect
@@ -0,0 +1,33 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        [yield] let dynamic #t1 = asy::_awaitHelper("Hello, World!", :async_op_then, :async_op_error, :async_op) in null;
+        core::print(:result);
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.direct.transformed.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.direct.transformed.expect
new file mode 100644
index 0000000..fb62763
--- /dev/null
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.direct.transformed.expect
@@ -0,0 +1,101 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set a(dynamic #synthetic) → dynamic
+    let dynamic _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:10:8: Error: A setter should have exactly one formal parameter.
+  set a();
+       ^";
+  set d(dynamic #synthetic) → dynamic
+    let dynamic _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:11:8: Error: A setter should have exactly one formal parameter.
+  set d(x, y);
+       ^";
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set a(dynamic #synthetic) → dynamic
+    let dynamic _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:15:8: Error: A setter should have exactly one formal parameter.
+  set a();
+       ^";
+  set d(dynamic #synthetic) → dynamic
+    let dynamic _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:16:8: Error: A setter should have exactly one formal parameter.
+  set d(x, y);
+       ^";
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/bad_setter_abstract.dart:5:8: Error: Expected a function body or '=>'.
+Try adding {}.
+set b();
+       ^", "pkg/front_end/testcases/bad_setter_abstract.dart:7:12: Error: Expected a function body or '=>'.
+Try adding {}.
+set c(x, y);
+           ^"]/* from null */;
+static set b(dynamic #synthetic) → dynamic
+  let dynamic _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:5:6: Error: A setter should have exactly one formal parameter.
+set b();
+     ^";
+static set c(dynamic #synthetic) → dynamic
+  let dynamic _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:7:6: Error: A setter should have exactly one formal parameter.
+set c(x, y);
+     ^";
+static method main() → dynamic {
+  core::bool threw;
+  try {
+    threw = true;
+    new self::A::•().a = null;
+    threw = false;
+  }
+  on dynamic catch(final dynamic e) {
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+  try {
+    threw = true;
+    new self::A::•().d = null;
+    threw = false;
+  }
+  on dynamic catch(final dynamic e) {
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+  try {
+    threw = true;
+    self::b = null;
+    threw = false;
+  }
+  on dynamic catch(final dynamic e) {
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+  try {
+    threw = true;
+    self::c = null;
+    threw = false;
+  }
+  on dynamic catch(final dynamic e) {
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+  try {
+    threw = true;
+    throw new core::AbstractClassInstantiationError::•("B");
+    threw = false;
+  }
+  on core::AbstractClassInstantiationError catch(final core::AbstractClassInstantiationError _) {
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+}
diff --git a/pkg/front_end/testcases/bad_setter_abstract.dart.strong.transformed.expect b/pkg/front_end/testcases/bad_setter_abstract.dart.strong.transformed.expect
new file mode 100644
index 0000000..6acf36b
--- /dev/null
+++ b/pkg/front_end/testcases/bad_setter_abstract.dart.strong.transformed.expect
@@ -0,0 +1,103 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set a(dynamic #synthetic) → void
+    let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:10:8: Error: A setter should have exactly one formal parameter.
+  set a();
+       ^";
+  set d(dynamic #synthetic) → void
+    let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:11:8: Error: A setter should have exactly one formal parameter.
+  set d(x, y);
+       ^";
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set a(dynamic #synthetic) → void
+    let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:15:8: Error: A setter should have exactly one formal parameter.
+  set a();
+       ^";
+  set d(dynamic #synthetic) → void
+    let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:16:8: Error: A setter should have exactly one formal parameter.
+  set d(x, y);
+       ^";
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/bad_setter_abstract.dart:5:8: Error: Expected a function body or '=>'.
+Try adding {}.
+set b();
+       ^", "pkg/front_end/testcases/bad_setter_abstract.dart:7:12: Error: Expected a function body or '=>'.
+Try adding {}.
+set c(x, y);
+           ^", "pkg/front_end/testcases/bad_setter_abstract.dart:66:9: Error: The class 'B' is abstract and can't be instantiated.
+    new B();
+        ^"]/* from null */;
+static set b(dynamic #synthetic) → void
+  let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:5:6: Error: A setter should have exactly one formal parameter.
+set b();
+     ^";
+static set c(dynamic #synthetic) → void
+  let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/bad_setter_abstract.dart:7:6: Error: A setter should have exactly one formal parameter.
+set c(x, y);
+     ^";
+static method main() → dynamic {
+  core::bool threw;
+  try {
+    threw = true;
+    new self::A::•().{self::A::a} = null;
+    threw = false;
+  }
+  on dynamic catch(final dynamic e) {
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+  try {
+    threw = true;
+    new self::A::•().{self::A::d} = null;
+    threw = false;
+  }
+  on dynamic catch(final dynamic e) {
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+  try {
+    threw = true;
+    self::b = null;
+    threw = false;
+  }
+  on dynamic catch(final dynamic e) {
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+  try {
+    threw = true;
+    self::c = null;
+    threw = false;
+  }
+  on dynamic catch(final dynamic e) {
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+  try {
+    threw = true;
+    throw new core::AbstractClassInstantiationError::•("B");
+    threw = false;
+  }
+  on core::AbstractClassInstantiationError catch(final core::AbstractClassInstantiationError _) {
+  }
+  if(!threw) {
+    throw "Expected an error above.";
+  }
+}
diff --git a/pkg/front_end/testcases/bad_store.dart.direct.transformed.expect b/pkg/front_end/testcases/bad_store.dart.direct.transformed.expect
new file mode 100644
index 0000000..2acd12e
--- /dev/null
+++ b/pkg/front_end/testcases/bad_store.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method identity(dynamic x) → dynamic
+  return x;
+static method use(dynamic x) → void {}
+static method main(core::List<core::String> args) → dynamic {
+  dynamic foo = self::identity(new self::Foo::•());
+  if(args.length.>(1)) {
+    foo.field = "string";
+    dynamic first = foo.field;
+    self::use(first);
+    foo.noField = "string";
+    dynamic second = foo.noField;
+    self::use(second);
+  }
+}
diff --git a/pkg/front_end/testcases/bad_store.dart.strong.transformed.expect b/pkg/front_end/testcases/bad_store.dart.strong.transformed.expect
new file mode 100644
index 0000000..9d63dac
--- /dev/null
+++ b/pkg/front_end/testcases/bad_store.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method identity(dynamic x) → dynamic
+  return x;
+static method use(dynamic x) → void {}
+static method main(core::List<core::String> args) → dynamic {
+  dynamic foo = self::identity(new self::Foo::•());
+  if(args.{core::List::length}.{core::num::>}(1)) {
+    foo.field = "string";
+    dynamic first = foo.field;
+    self::use(first);
+    foo.noField = "string";
+    dynamic second = foo.noField;
+    self::use(second);
+  }
+}
diff --git a/pkg/front_end/testcases/bug21938.dart.direct.transformed.expect b/pkg/front_end/testcases/bug21938.dart.direct.transformed.expect
new file mode 100644
index 0000000..a399b1b
--- /dev/null
+++ b/pkg/front_end/testcases/bug21938.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  core::Object x;
+  core::Function f;
+  x.call();
+  x.call(3);
+  f.call(5, 2);
+  x.call();
+  f.call;
+  f.call(5, 2);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/bug30695.dart.direct.transformed.expect b/pkg/front_end/testcases/bug30695.dart.direct.transformed.expect
new file mode 100644
index 0000000..b07b4f4
--- /dev/null
+++ b/pkg/front_end/testcases/bug30695.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic foo = 42;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  method foo() → dynamic
+    return 42;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/bug31124.dart.direct.transformed.expect b/pkg/front_end/testcases/bug31124.dart.direct.transformed.expect
new file mode 100644
index 0000000..e470ed2
--- /dev/null
+++ b/pkg/front_end/testcases/bug31124.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static method #main() → dynamic {
+  throw "pkg/front_end/testcases/bug31124.dart:1:1: Error: Duplicated name: a
+var a = () => 'b';a();
+^";
+}
diff --git a/pkg/front_end/testcases/bug31124.dart.strong.transformed.expect b/pkg/front_end/testcases/bug31124.dart.strong.transformed.expect
new file mode 100644
index 0000000..e470ed2
--- /dev/null
+++ b/pkg/front_end/testcases/bug31124.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static method #main() → dynamic {
+  throw "pkg/front_end/testcases/bug31124.dart:1:1: Error: Duplicated name: a
+var a = () => 'b';a();
+^";
+}
diff --git a/pkg/front_end/testcases/bug32426.dart.direct.transformed.expect b/pkg/front_end/testcases/bug32426.dart.direct.transformed.expect
new file mode 100644
index 0000000..1e86267
--- /dev/null
+++ b/pkg/front_end/testcases/bug32426.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method call() → void;
+}
+class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call([core::int x = null]) → void {}
+}
+static method main() → dynamic {
+  self::I i = new self::C::•();
+  ([core::int]) → void f = i;
+}
diff --git a/pkg/front_end/testcases/bug32426.dart.strong.transformed.expect b/pkg/front_end/testcases/bug32426.dart.strong.transformed.expect
new file mode 100644
index 0000000..4c681bf
--- /dev/null
+++ b/pkg/front_end/testcases/bug32426.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method call() → void;
+}
+class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call([core::int x = null]) → void {}
+}
+static method main() → dynamic {
+  self::I i = new self::C::•();
+  ([core::int]) → void f = (let final self::I #t1 = i in #t1.==(null) ?{() → void} null : #t1.{self::I::call}) as{TypeError} ([core::int]) → void;
+}
diff --git a/pkg/front_end/testcases/cascade.dart.direct.transformed.expect b/pkg/front_end/testcases/cascade.dart.direct.transformed.expect
new file mode 100644
index 0000000..f2cd187
--- /dev/null
+++ b/pkg/front_end/testcases/cascade.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  dynamic list = let final dynamic #t1 = <dynamic>[1] in let final dynamic #t2 = #t1.add(2) in let final dynamic #t3 = #t1.add(3) in let final dynamic #t4 = #t1.addAll(<dynamic>[4, 5]) in #t1;
+  core::print(list);
+  let final dynamic #t5 = list in let final dynamic #t6 = #t5.add(2) in let final dynamic #t7 = #t5.length in let final dynamic #t8 = #t5.length = 0 in #t5;
+  core::print(list);
+  let final dynamic #t9 = list in let final dynamic #t10 = #t9.add(2) in let final dynamic #t11 = #t9.[](0) in let final dynamic #t12 = #t9.[]=(0, 87) in #t9;
+  core::print(list);
+  list = let final dynamic #t13 = <dynamic>[<dynamic>[1]] in let final dynamic #t14 = #t13.first.last.toString() in let final dynamic #t15 = #t13.first.[](0).toString() in let final dynamic #t16 = #t13.[](0).last.toString() in #t13;
+  core::print(list);
+}
diff --git a/pkg/front_end/testcases/casts.dart.direct.transformed.expect b/pkg/front_end/testcases/casts.dart.direct.transformed.expect
new file mode 100644
index 0000000..c75d8ec
--- /dev/null
+++ b/pkg/front_end/testcases/casts.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("" as core::String);
+  core::print(1 as core::int);
+  core::print(1.0 as core::double);
+  core::print("" is core::String);
+  core::print("" is core::int);
+  core::print("" is core::double);
+  core::print(1 is core::String);
+  core::print(1 is core::int);
+  core::print(1 is core::double);
+  core::print(1.0 is core::String);
+  core::print(1.0 is core::int);
+  core::print(1.0 is core::double);
+}
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.direct.transformed.expect
new file mode 100644
index 0000000..25dc9b8
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in new def::C::•());
+}
diff --git a/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect
new file mode 100644
index 0000000..d62c43e
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_allocation.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print(let final core::Object #t1 = CheckLibraryIsLoaded(lib) in new def::C::•());
+}
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.direct.transformed.expect
new file mode 100644
index 0000000..d17f162
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic {}
+static method test(dynamic x) → dynamic {
+  x as invalid-type;
+}
diff --git a/pkg/front_end/testcases/check_deferred_as_check.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_as_check.dart.strong.transformed.expect
new file mode 100644
index 0000000..142e594
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_as_check.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/check_deferred_as_check.dart:9:8: Error: The type '#lib1::C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
+Try removing 'deferred' from the import of 'lib' or use a supertype of '#lib1::C' that isn't deferred.
+  x as lib.C;
+       ^^^"]/* from null */;
+static method main() → dynamic {}
+static method test(dynamic x) → dynamic {
+  x as invalid-type;
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.direct.transformed.expect
new file mode 100644
index 0000000..0ff5bf9
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = self::m2();
+  let final dynamic #t2 = CheckLibraryIsLoaded(lib) in def::m(self::m2());
+}
+static method m2() → dynamic
+  return 1;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect
new file mode 100644
index 0000000..74489ed
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::x = self::m2();
+  let final core::Object #t2 = CheckLibraryIsLoaded(lib) in def::m(self::m2());
+}
+static method m2() → dynamic
+  return 1;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.direct.transformed.expect
new file mode 100644
index 0000000..8716818
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.direct.transformed.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        final dynamic #t1 = CheckLibraryIsLoaded(lib);
+        [yield] let dynamic #t2 = asy::_awaitHelper(LoadLibrary(lib), :async_op_then, :async_op_error, :async_op) in null;
+        def::m(:result);
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect
new file mode 100644
index 0000000..342fff7
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        final core::Object #t1 = CheckLibraryIsLoaded(lib);
+        [yield] let dynamic #t2 = asy::_awaitHelper(LoadLibrary(lib), :async_op_then, :async_op_error, :async_op) in null;
+        def::m(:result);
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.direct.transformed.expect
new file mode 100644
index 0000000..9aef4cf
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(3);
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect
new file mode 100644
index 0000000..1eb7ae1
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::m(3);
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.direct.transformed.expect
new file mode 100644
index 0000000..2b7ef3d
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = 2;
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect
new file mode 100644
index 0000000..d51e9f3
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::x = 2;
+}
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.direct.transformed.expect
new file mode 100644
index 0000000..8fa0c48
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {}
+static method test(dynamic x) → dynamic {
+  core::print(x is invalid-type);
+}
diff --git a/pkg/front_end/testcases/check_deferred_is_check.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_is_check.dart.strong.transformed.expect
new file mode 100644
index 0000000..ef6d460
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_is_check.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/check_deferred_is_check.dart:9:14: Error: The type '#lib1::C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
+Try removing 'deferred' from the import of 'lib' or use a supertype of '#lib1::C' that isn't deferred.
+  print(x is lib.C);
+             ^^^"]/* from null */;
+static method main() → dynamic {}
+static method test(dynamic x) → dynamic {
+  core::print(x is invalid-type);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_read.dart.direct.transformed.expect
new file mode 100644
index 0000000..5fd285b
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print((let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x).+(1));
+}
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect
new file mode 100644
index 0000000..f01fe12
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print((let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::x).{core::num::+}(1));
+}
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..7b3c2df
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::y);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..a3557a6
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_static_field.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print(let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::C::y);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..4c3620c
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..555229f
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read_type.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print(let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::C);
+}
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.direct.transformed.expect
new file mode 100644
index 0000000..05236e5
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print(let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::C::m());
+}
diff --git a/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect
new file mode 100644
index 0000000..c5ab3c3
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_static_method_call.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print(let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::C::m());
+}
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.direct.transformed.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.direct.transformed.expect
new file mode 100644
index 0000000..fe4fe2e
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  return self::test();
+static method test() → dynamic {
+  invalid-type x = null;
+}
diff --git a/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.transformed.expect
new file mode 100644
index 0000000..4d6d46d
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_type_declaration.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/check_deferred_type_declaration.dart:9:3: Error: The type '#lib1::C' is deferred loaded via prefix 'lib' and can't be used as a type annotation.
+Try removing 'deferred' from the import of 'lib' or use a supertype of '#lib1::C' that isn't deferred.
+  lib.C x = null;
+  ^^^"]/* from null */;
+static method main() → dynamic
+  return self::test();
+static method test() → dynamic {
+  invalid-type x = null;
+}
diff --git a/pkg/front_end/testcases/classes.dart.direct.transformed.expect b/pkg/front_end/testcases/classes.dart.direct.transformed.expect
new file mode 100644
index 0000000..8cb3ab3
--- /dev/null
+++ b/pkg/front_end/testcases/classes.dart.direct.transformed.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x;
+  final field core::int y;
+  constructor •(core::int y) → void
+    : self::A::y = y, self::A::x = 42, super core::Object::•()
+    ;
+  method method() → dynamic {
+    core::print("A.method x: ${this.{self::A::x}} y: ${this.{self::A::y}}");
+    core::print(this);
+    core::print(this.{core::Object::runtimeType});
+  }
+}
+class B extends self::A {
+  constructor •(dynamic x) → void
+    : super self::A::•(x)
+    ;
+  method method() → dynamic {
+    core::print("B.method x: ${this.{self::A::x}} y: ${this.{self::A::y}}");
+    super.{self::A::method}();
+  }
+}
+static method main() → dynamic {
+  self::A a = new self::A::•(87);
+  self::B b = new self::B::•(117);
+  a.method();
+  b.method();
+}
diff --git a/pkg/front_end/testcases/closure.dart.direct.transformed.expect b/pkg/front_end/testcases/closure.dart.direct.transformed.expect
new file mode 100644
index 0000000..edc6bf4
--- /dev/null
+++ b/pkg/front_end/testcases/closure.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic _field = new self::Bar::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method useCallback(dynamic callback) → dynamic {
+  dynamic _ = callback.call();
+}
+static method main() → dynamic {
+  dynamic x;
+  function inner() → dynamic {
+    x = new self::Foo::•();
+    return new self::Foo::•();
+  }
+  self::useCallback(inner);
+  dynamic _ = inner.call()._field;
+}
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.direct.transformed.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.direct.transformed.expect
new file mode 100644
index 0000000..7b807bd
--- /dev/null
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static method #main() → dynamic {
+  throw "pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:9: Error: Duplicated name: A
+class A {
+        ^";
+}
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.transformed.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.transformed.expect
new file mode 100644
index 0000000..7b807bd
--- /dev/null
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static method #main() → dynamic {
+  throw "pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:9: Error: Duplicated name: A
+class A {
+        ^";
+}
diff --git a/pkg/front_end/testcases/covariant_generic.dart.direct.transformed.expect b/pkg/front_end/testcases/covariant_generic.dart.direct.transformed.expect
new file mode 100644
index 0000000..6c077b6
--- /dev/null
+++ b/pkg/front_end/testcases/covariant_generic.dart.direct.transformed.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Callback<T extends core::Object> = (T) → void;
+class Foo<T extends core::Object> extends core::Object {
+  final field self::Foo::T finalField;
+  final field (self::Foo::T) → void callbackField;
+  field self::Foo::T mutableField = null;
+  field (self::Foo::T) → void mutableCallbackField = null;
+  constructor •(self::Foo::T finalField, (self::Foo::T) → void callbackField) → void
+    : self::Foo::finalField = finalField, self::Foo::callbackField = callbackField, super core::Object::•()
+    ;
+  method method(self::Foo::T x) → void {}
+  set setter(self::Foo::T x) → dynamic {}
+  method withCallback((self::Foo::T) → void callback) → void {
+    callback.call(this.{self::Foo::finalField});
+  }
+}
+static method main() → dynamic {
+  self::Foo<core::int> fooInt = new self::Foo::•<core::int>(1, (core::int x) → dynamic {});
+  fooInt.method(3);
+  fooInt.setter = 3;
+  fooInt.withCallback((core::int x) → dynamic {});
+  fooInt.withCallback((core::num x) → dynamic {});
+  fooInt.mutableField = 3;
+  fooInt.mutableCallbackField = (core::int x) → dynamic {};
+  self::Foo<core::num> fooNum = fooInt;
+  fooNum.method(3);
+  fooNum.method(2.5);
+  fooNum.setter = 3;
+  fooNum.setter = 2.5;
+  fooNum.withCallback((core::num x) → dynamic {});
+  fooNum.mutableField = 3;
+  fooNum.mutableField = 2.5;
+  fooNum.mutableCallbackField(3);
+  fooNum.mutableCallbackField(2.5);
+  fooNum.mutableCallbackField = (core::num x) → dynamic {};
+}
diff --git a/pkg/front_end/testcases/cycles.dart.direct.transformed.expect b/pkg/front_end/testcases/cycles.dart.direct.transformed.expect
new file mode 100644
index 0000000..930f646
--- /dev/null
+++ b/pkg/front_end/testcases/cycles.dart.direct.transformed.expect
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/cycles.dart:5:7: Error: 'A' is a supertype of itself via 'B', 'C'.
+class A implements C {}
+      ^", "pkg/front_end/testcases/cycles.dart:7:7: Error: 'B' is a supertype of itself via 'A', 'C'.
+class B extends A {}
+      ^", "pkg/front_end/testcases/cycles.dart:9:7: Error: 'C' is a supertype of itself via 'A', 'B'.
+class C extends B implements D {}
+      ^"]/* from null */;
+static method main() → dynamic {
+  core::print(new self::A::•());
+  core::print(new self::B::•());
+  core::print(new self::C::•());
+  core::print(new self::D::•());
+}
diff --git a/pkg/front_end/testcases/default_values.dart.direct.transformed.expect b/pkg/front_end/testcases/default_values.dart.direct.transformed.expect
new file mode 100644
index 0000000..ac79608
--- /dev/null
+++ b/pkg/front_end/testcases/default_values.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method topLevel([dynamic a = 42]) → dynamic
+  return a;
+static method main() → dynamic {
+  core::print(self::topLevel());
+}
diff --git a/pkg/front_end/testcases/duplicated_named_args_3.dart.direct.transformed.expect b/pkg/front_end/testcases/duplicated_named_args_3.dart.direct.transformed.expect
new file mode 100644
index 0000000..e95737c
--- /dev/null
+++ b/pkg/front_end/testcases/duplicated_named_args_3.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method m({core::int a = 0}) → dynamic {}
+}
+static method test() → void {
+  self::C::m(a: invalid-expression "pkg/front_end/testcases/duplicated_named_args_3.dart:13:19: Error: Duplicated named argument 'a'.
+  C.m(a: 1, a: 2, a: 3);
+                  ^");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.transformed.expect b/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.transformed.expect
new file mode 100644
index 0000000..6fc51ce
--- /dev/null
+++ b/pkg/front_end/testcases/duplicated_named_args_3.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method m({core::int a = 0}) → dynamic {}
+}
+static method test() → void {
+  self::C::m(a: invalid-expression "pkg/front_end/testcases/duplicated_named_args_3.dart:13:19: Error: Duplicated named argument 'a'.
+  C.m(a: 1, a: 2, a: 3);
+                  ^" as{TypeError} core::int);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/dynamic_and_void.dart.direct.transformed.expect b/pkg/front_end/testcases/dynamic_and_void.dart.direct.transformed.expect
new file mode 100644
index 0000000..4b7b5f6
--- /dev/null
+++ b/pkg/front_end/testcases/dynamic_and_void.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method testDynamic() → invalid-type
+  return 0;
+static method testVoid() → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/escape.dart.direct.transformed.expect b/pkg/front_end/testcases/escape.dart.direct.transformed.expect
new file mode 100644
index 0000000..136725f
--- /dev/null
+++ b/pkg/front_end/testcases/escape.dart.direct.transformed.expect
@@ -0,0 +1,50 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator ==(dynamic x) → dynamic
+    return false;
+}
+class X extends core::Object implements self::A, self::B {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method useAsA(self::A object) → void {
+  dynamic _ = object.field;
+}
+static method useAsB(self::B object) → void {
+  dynamic _ = object.field;
+  self::escape(object);
+}
+static method escape(dynamic x) → void {
+  x.==(null) ? x = "" : null;
+  x.==(null) ? x = 45 : null;
+  if(!(x is core::int) && !(x is core::String)) {
+    x.field = 45;
+  }
+}
+static method main() → dynamic {
+  dynamic object = new self::X::•();
+  self::useAsA(new self::A::•());
+  self::useAsA(object);
+  self::useAsB(new self::B::•());
+  self::useAsB(object);
+}
diff --git a/pkg/front_end/testcases/export_main.dart.direct.transformed.expect b/pkg/front_end/testcases/export_main.dart.direct.transformed.expect
new file mode 100644
index 0000000..9227cd5
--- /dev/null
+++ b/pkg/front_end/testcases/export_main.dart.direct.transformed.expect
@@ -0,0 +1,4 @@
+library;
+import self as self;
+import "./hello.dart" as hel;
+additionalExports = (hel::main)
diff --git a/pkg/front_end/testcases/export_main.dart.strong.transformed.expect b/pkg/front_end/testcases/export_main.dart.strong.transformed.expect
new file mode 100644
index 0000000..9227cd5
--- /dev/null
+++ b/pkg/front_end/testcases/export_main.dart.strong.transformed.expect
@@ -0,0 +1,4 @@
+library;
+import self as self;
+import "./hello.dart" as hel;
+additionalExports = (hel::main)
diff --git a/pkg/front_end/testcases/export_test.dart.direct.transformed.expect b/pkg/front_end/testcases/export_test.dart.direct.transformed.expect
new file mode 100644
index 0000000..40ce1cc
--- /dev/null
+++ b/pkg/front_end/testcases/export_test.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:developer" as dev;
+additionalExports = (core::print)
+
+static method main() → dynamic {
+  core::print(dev::UserTag);
+}
diff --git a/pkg/front_end/testcases/export_test.dart.strong.transformed.expect b/pkg/front_end/testcases/export_test.dart.strong.transformed.expect
new file mode 100644
index 0000000..40ce1cc
--- /dev/null
+++ b/pkg/front_end/testcases/export_test.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:developer" as dev;
+additionalExports = (core::print)
+
+static method main() → dynamic {
+  core::print(dev::UserTag);
+}
diff --git a/pkg/front_end/testcases/expressions.dart.direct.transformed.expect b/pkg/front_end/testcases/expressions.dart.direct.transformed.expect
new file mode 100644
index 0000000..7fece02
--- /dev/null
+++ b/pkg/front_end/testcases/expressions.dart.direct.transformed.expect
@@ -0,0 +1,79 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method foo({dynamic fisk = null}) → dynamic {
+  core::print(fisk);
+}
+static method caller(dynamic f) → dynamic {
+  f.call();
+}
+static method main() → dynamic {
+  core::int i = 0;
+  core::print(i.==(1) ? "bad" : "good");
+  core::print("${i}");
+  core::print("'${i}'");
+  core::print(" '${i}' ");
+  core::print(" '${i}' '${i}'");
+  core::print(" '${i}' '${i}'");
+  core::print("foobar");
+  core::print(" '${i}' '${i}' '${i}' '${i}'");
+  try {
+    throw "fisk";
+  }
+  on core::String catch(final core::String e, final core::StackTrace s) {
+    core::print(e);
+    if(!s.==(null))
+      core::print(s);
+  }
+  for (; false; ) {
+  }
+  dynamic list = <dynamic>["Hello, World!"];
+  core::print(list.[](i));
+  list.[]=(i, "Hello, Brave New World!");
+  core::print(list.[](i));
+  i = 87;
+  core::print(i.unary-());
+  core::print(i.~());
+  core::print(!i.==(42));
+  core::print(i = i.-(1));
+  core::print(i = i.+(1));
+  core::print(let final dynamic #t1 = i in let final dynamic #t2 = i = #t1.-(1) in #t1);
+  core::print(let final dynamic #t3 = i in let final dynamic #t4 = i = #t3.+(1) in #t3);
+  core::print(new core::Object::•());
+  core::print(const core::Object::•());
+  core::print(core::List::•<core::String>(2).runtimeType);
+  self::foo(fisk: "Blorp gulp");
+  function f() → dynamic {
+    core::print("f was called");
+  }
+  self::caller(f);
+  self::caller(() → dynamic {
+    core::print("<anon> was called");
+  });
+  function g([dynamic message = null]) → dynamic {
+    core::print(message);
+  }
+  g.call("Hello, World");
+  self::caller(([dynamic x = null]) → dynamic {
+    core::print("<anon> was called with ${x}");
+  });
+  function h({dynamic message = null}) → dynamic {
+    core::print(message);
+  }
+  h.call(message: "Hello, World");
+  self::caller(({dynamic x = null}) → dynamic {
+    core::print("<anon> was called with ${x}");
+  });
+  core::print(core::int.toString());
+  core::print(core::int);
+  core::print(let final dynamic #t5 = core::int in let final dynamic #t6 = #t5.toString() in #t5);
+  try {
+    core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#int.toString, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    throw "Shouldn't work";
+  }
+  on core::NoSuchMethodError catch(final core::NoSuchMethodError e) {
+    core::print("As expected: ${e}");
+  }
+  core::print(core::int::parse("42"));
+}
diff --git a/pkg/front_end/testcases/expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/expressions.dart.strong.transformed.expect
new file mode 100644
index 0000000..c122e52
--- /dev/null
+++ b/pkg/front_end/testcases/expressions.dart.strong.transformed.expect
@@ -0,0 +1,82 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/expressions.dart:74:16: Error: Method not found: 'int.toString'.
+    print(int?.toString());
+               ^^^^^^^^"]/* from null */;
+static method foo({dynamic fisk = null}) → dynamic {
+  core::print(fisk);
+}
+static method caller(dynamic f) → dynamic {
+  f.call();
+}
+static method main() → dynamic {
+  core::int i = 0;
+  core::print(i.{core::num::==}(1) ?{core::String} "bad" : "good");
+  core::print("${i}");
+  core::print("'${i}'");
+  core::print(" '${i}' ");
+  core::print(" '${i}' '${i}'");
+  core::print(" '${i}' '${i}'");
+  core::print("foobar");
+  core::print(" '${i}' '${i}' '${i}' '${i}'");
+  try {
+    throw "fisk";
+  }
+  on core::String catch(final core::String e, final core::StackTrace s) {
+    core::print(e);
+    if(!s.{core::Object::==}(null))
+      core::print(s);
+  }
+  for (; false; ) {
+  }
+  core::List<core::String> list = <core::String>["Hello, World!"];
+  core::print(list.{core::List::[]}(i));
+  list.{core::List::[]=}(i, "Hello, Brave New World!");
+  core::print(list.{core::List::[]}(i));
+  i = 87;
+  core::print(i.{core::int::unary-}());
+  core::print(i.{core::int::~}());
+  core::print(!i.{core::num::==}(42));
+  core::print(i = i.{core::num::-}(1));
+  core::print(i = i.{core::num::+}(1));
+  core::print(let final core::int #t1 = i in let final core::int #t2 = i = #t1.{core::num::-}(1) in #t1);
+  core::print(let final core::int #t3 = i in let final core::int #t4 = i = #t3.{core::num::+}(1) in #t3);
+  core::print(new core::Object::•());
+  core::print(const core::Object::•());
+  core::print(core::List::•<core::String>(2).{core::Object::runtimeType});
+  self::foo(fisk: "Blorp gulp");
+  function f() → core::Null {
+    core::print("f was called");
+  }
+  self::caller(f);
+  self::caller(() → core::Null {
+    core::print("<anon> was called");
+  });
+  function g([dynamic message = null]) → core::Null {
+    core::print(message);
+  }
+  g.call("Hello, World");
+  self::caller(([dynamic x = null]) → core::Null {
+    core::print("<anon> was called with ${x}");
+  });
+  function h({dynamic message = null}) → core::Null {
+    core::print(message);
+  }
+  h.call(message: "Hello, World");
+  self::caller(({dynamic x = null}) → core::Null {
+    core::print("<anon> was called with ${x}");
+  });
+  core::print(core::int.{core::Object::toString}());
+  core::print(core::int);
+  core::print(let final core::Type #t5 = core::int in let final core::String #t6 = #t5.{core::Object::toString}() in #t5);
+  try {
+    core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#int.toString, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    throw "Shouldn't work";
+  }
+  on core::NoSuchMethodError catch(final core::NoSuchMethodError e) {
+    core::print("As expected: ${e}");
+  }
+  core::print(core::int::parse("42"));
+}
diff --git a/pkg/front_end/testcases/external.dart.direct.transformed.expect b/pkg/front_end/testcases/external.dart.direct.transformed.expect
new file mode 100644
index 0000000..273c277
--- /dev/null
+++ b/pkg/front_end/testcases/external.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:isolate" as iso;
+
+static field dynamic subscription;
+static method onData(dynamic x) → void {
+  core::print(x);
+  self::subscription.cancel();
+}
+static method main() → dynamic {
+  dynamic string = core::String::fromCharCode(65);
+  dynamic port = iso::ReceivePort::•();
+  self::subscription = port.listen(self::onData);
+  port.sendPort.send(string);
+}
diff --git a/pkg/front_end/testcases/external_import.dart.direct.transformed.expect b/pkg/front_end/testcases/external_import.dart.direct.transformed.expect
new file mode 100644
index 0000000..145e77a
--- /dev/null
+++ b/pkg/front_end/testcases/external_import.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+@dart._internal::ExternalName::•("org-dartlang-testcase:///here")
+@dart._internal::ExternalName::•("org-dartlang-testcase:///there")
+@dart._internal::ExternalName::•("file:///usr/local/somewhere")
+library;
+import self as self;
+
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/external_import.dart.strong.transformed.expect b/pkg/front_end/testcases/external_import.dart.strong.transformed.expect
new file mode 100644
index 0000000..145e77a
--- /dev/null
+++ b/pkg/front_end/testcases/external_import.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+@dart._internal::ExternalName::•("org-dartlang-testcase:///here")
+@dart._internal::ExternalName::•("org-dartlang-testcase:///there")
+@dart._internal::ExternalName::•("file:///usr/local/somewhere")
+library;
+import self as self;
+
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/fibonacci.dart.direct.transformed.expect b/pkg/front_end/testcases/fibonacci.dart.direct.transformed.expect
new file mode 100644
index 0000000..c46429a
--- /dev/null
+++ b/pkg/front_end/testcases/fibonacci.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method fibonacci(core::int n) → core::int {
+  if(n.<(2))
+    return n;
+  return self::fibonacci(n.-(1)).+(self::fibonacci(n.-(2)));
+}
+static method main() → dynamic {
+  for (core::int i = 0; i.<(20); i = i.+(1)) {
+    core::print(self::fibonacci(i));
+  }
+}
diff --git a/pkg/front_end/testcases/for_in_scope.dart.direct.transformed.expect b/pkg/front_end/testcases/for_in_scope.dart.direct.transformed.expect
new file mode 100644
index 0000000..624010c
--- /dev/null
+++ b/pkg/front_end/testcases/for_in_scope.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main(core::List<core::String> arguments) → dynamic {
+  for (core::String arguments in arguments) {
+    core::print(arguments);
+  }
+}
diff --git a/pkg/front_end/testcases/function_in_field.dart.direct.transformed.expect b/pkg/front_end/testcases/function_in_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..f5a4253
--- /dev/null
+++ b/pkg/front_end/testcases/function_in_field.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic x = () → dynamic {
+  dynamic y = 42;
+  return y;
+};
+static method main() → dynamic {
+  core::print(self::x.call());
+}
diff --git a/pkg/front_end/testcases/function_type_is_check.dart.direct.transformed.expect b/pkg/front_end/testcases/function_type_is_check.dart.direct.transformed.expect
new file mode 100644
index 0000000..47e3281
--- /dev/null
+++ b/pkg/front_end/testcases/function_type_is_check.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+static method test(dynamic f) → dynamic {
+  if(f is (core::Object, core::StackTrace) → void)
+    return 1;
+  if(f is (core::Object) → void)
+    return 10;
+  if(f is () → void)
+    return 100;
+}
+static method main() → dynamic {
+  exp::Expect::equals(111, self::test(() → dynamic => null).+(self::test((core::Object o) → dynamic => null)).+(self::test((core::Object o, core::StackTrace t) → dynamic => null)));
+}
diff --git a/pkg/front_end/testcases/function_type_is_check.dart.strong.transformed.expect b/pkg/front_end/testcases/function_type_is_check.dart.strong.transformed.expect
new file mode 100644
index 0000000..f827885
--- /dev/null
+++ b/pkg/front_end/testcases/function_type_is_check.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+static method test(dynamic f) → dynamic {
+  if(f is (core::Object, core::StackTrace) → void)
+    return 1;
+  if(f is (core::Object) → void)
+    return 10;
+  if(f is () → void)
+    return 100;
+}
+static method main() → dynamic {
+  exp::Expect::equals(111, self::test(() → core::Null => null).+(self::test((core::Object o) → core::Null => null)).+(self::test((core::Object o, core::StackTrace t) → core::Null => null)));
+}
diff --git a/pkg/front_end/testcases/functions.dart.direct.transformed.expect b/pkg/front_end/testcases/functions.dart.direct.transformed.expect
new file mode 100644
index 0000000..a816760
--- /dev/null
+++ b/pkg/front_end/testcases/functions.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  function local(({a: dynamic}) → void f) → void {
+    f.call(a: "Hello, World");
+    f.call();
+  }
+  local.call(({dynamic a = "Default greeting!"}) → dynamic {
+    core::print(a);
+  });
+}
diff --git a/pkg/front_end/testcases/future_or_test.dart.direct.transformed.expect b/pkg/front_end/testcases/future_or_test.dart.direct.transformed.expect
new file mode 100644
index 0000000..dbae521
--- /dev/null
+++ b/pkg/front_end/testcases/future_or_test.dart.direct.transformed.expect
@@ -0,0 +1,79 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return null;
+}
+class B extends core::Object {
+  field self::A a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method bar() → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = this.{self::B::a}.foo();
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+}
+class C extends core::Object {
+  field self::B b = new self::B::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method baz() → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          :return_value = this.{self::C::b}.bar();
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/future_or_test.dart.strong.transformed.expect b/pkg/front_end/testcases/future_or_test.dart.strong.transformed.expect
new file mode 100644
index 0000000..b18f9fb
--- /dev/null
+++ b/pkg/front_end/testcases/future_or_test.dart.strong.transformed.expect
@@ -0,0 +1,79 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return null;
+}
+class B extends core::Object {
+  field self::A a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method bar() → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = this.{self::B::a}.{self::A::foo}();
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+}
+class C extends core::Object {
+  field self::B b = new self::B::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method baz() → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          :return_value = this.{self::C::b}.{self::B::bar}() as{TypeError} asy::FutureOr<core::int>;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/hello.dart.direct.transformed.expect b/pkg/front_end/testcases/hello.dart.direct.transformed.expect
new file mode 100644
index 0000000..fea7b39
--- /dev/null
+++ b/pkg/front_end/testcases/hello.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/illegal_named_function_expression.dart.direct.transformed.expect b/pkg/front_end/testcases/illegal_named_function_expression.dart.direct.transformed.expect
new file mode 100644
index 0000000..dc19dc1
--- /dev/null
+++ b/pkg/front_end/testcases/illegal_named_function_expression.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/illegal_named_function_expression.dart:6:11: Error: A function expression can't have a return type.
+  var x = void f<T>(T t) {};
+          ^^^^", "pkg/front_end/testcases/illegal_named_function_expression.dart:6:16: Error: A function expression can't have a name.
+  var x = void f<T>(T t) {};
+               ^", "pkg/front_end/testcases/illegal_named_function_expression.dart:8:9: Error: A function expression can't have a return type.
+  print(void g<T>(T t) {});
+        ^^^^", "pkg/front_end/testcases/illegal_named_function_expression.dart:8:14: Error: A function expression can't have a name.
+  print(void g<T>(T t) {});
+             ^"]/* from null */;
+static method main() → dynamic {
+  dynamic x = let final <T extends core::Object>(T) → void f = <T extends core::Object>(T t) → dynamic {} in f;
+  core::print(x.runtimeType);
+  core::print(let final <T extends core::Object>(T) → void g = <T extends core::Object>(T t) → dynamic {} in g);
+}
diff --git a/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.transformed.expect b/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.transformed.expect
new file mode 100644
index 0000000..f1c5274
--- /dev/null
+++ b/pkg/front_end/testcases/illegal_named_function_expression.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/illegal_named_function_expression.dart:6:11: Error: A function expression can't have a return type.
+  var x = void f<T>(T t) {};
+          ^^^^", "pkg/front_end/testcases/illegal_named_function_expression.dart:6:16: Error: A function expression can't have a name.
+  var x = void f<T>(T t) {};
+               ^", "pkg/front_end/testcases/illegal_named_function_expression.dart:8:9: Error: A function expression can't have a return type.
+  print(void g<T>(T t) {});
+        ^^^^", "pkg/front_end/testcases/illegal_named_function_expression.dart:8:14: Error: A function expression can't have a name.
+  print(void g<T>(T t) {});
+             ^"]/* from null */;
+static method main() → dynamic {
+  <T extends core::Object>(T) → core::Null x = let final <T extends core::Object>(T) → core::Null f = <T extends core::Object>(T t) → core::Null {} in f;
+  core::print(x.{core::Object::runtimeType});
+  core::print(let final <T extends core::Object>(T) → core::Null g = <T extends core::Object>(T t) → core::Null {} in g);
+}
diff --git a/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.direct.transformed.expect b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.direct.transformed.expect
new file mode 100644
index 0000000..0bff178
--- /dev/null
+++ b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:9: Error: A function expression can't have a return type.
+  print(void f() {});
+        ^^^^", "pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:14: Error: A function expression can't have a name.
+  print(void f() {});
+             ^"]/* from null */;
+static method main() → dynamic {
+  function f() → void {}
+  core::print(let final () → void f = () → dynamic {} in f);
+}
diff --git a/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.transformed.expect
new file mode 100644
index 0000000..9c4d9bd
--- /dev/null
+++ b/pkg/front_end/testcases/illegal_named_function_expression_scope.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:9: Error: A function expression can't have a return type.
+  print(void f() {});
+        ^^^^", "pkg/front_end/testcases/illegal_named_function_expression_scope.dart:7:14: Error: A function expression can't have a name.
+  print(void f() {});
+             ^"]/* from null */;
+static method main() → dynamic {
+  function f() → void {}
+  core::print(let final () → core::Null f = () → core::Null {} in f);
+}
diff --git a/pkg/front_end/testcases/implicit_new.dart.direct.transformed.expect b/pkg/front_end/testcases/implicit_new.dart.direct.transformed.expect
new file mode 100644
index 0000000..4262af7
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_new.dart.direct.transformed.expect
@@ -0,0 +1,59 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → dynamic
+    return null;
+}
+class Bar extends core::Object {
+  constructor named() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → dynamic
+    return null;
+}
+class IndexTester extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](dynamic _) → dynamic
+    return null;
+  operator []=(dynamic _a, dynamic _b) → void {}
+}
+static method testNSM() → dynamic {
+  dynamic y = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Bar, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Bar, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+}
+static method f(dynamic x) → dynamic
+  return x;
+static method main() → dynamic {
+  dynamic x = new self::Foo::•();
+  x = new self::Foo::•();
+  dynamic z = new self::Bar::named();
+  z = new self::Bar::named();
+  self::f(new self::Foo::•());
+  self::f(new self::Foo::•());
+  self::f(new self::Bar::named());
+  self::f(new self::Bar::named());
+  dynamic l = <dynamic>[new self::Foo::•(), new self::Bar::named()];
+  l = <dynamic>[new self::Foo::•(), new self::Bar::named()];
+  dynamic m = <dynamic, dynamic>{"foo": new self::Foo::•(), "bar": new self::Bar::named()};
+  m = <dynamic, dynamic>{"foo": new self::Foo::•(), "bar": new self::Bar::named()};
+  dynamic i = new self::IndexTester::•();
+  i.[](new self::Foo::•());
+  i.[](new self::Foo::•());
+  i.[](new self::Bar::named());
+  i.[](new self::Bar::named());
+  i.[]=(new self::Foo::•(), null);
+  i.[]=(new self::Foo::•(), null);
+  i.[]=(new self::Bar::named(), null);
+  i.[]=(new self::Bar::named(), null);
+  new self::Foo::•().+(new self::Bar::named());
+  new self::Foo::•().+(new self::Bar::named());
+  new self::Bar::named().+(new self::Foo::•());
+  new self::Bar::named().+(new self::Foo::•());
+}
diff --git a/pkg/front_end/testcases/implicit_new.dart.strong.transformed.expect b/pkg/front_end/testcases/implicit_new.dart.strong.transformed.expect
new file mode 100644
index 0000000..d959e33
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_new.dart.strong.transformed.expect
@@ -0,0 +1,64 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → dynamic
+    return null;
+}
+class Bar extends core::Object {
+  constructor named() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → dynamic
+    return null;
+}
+class IndexTester extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](dynamic _) → dynamic
+    return null;
+  operator []=(dynamic _a, dynamic _b) → void {}
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/implicit_new.dart:18:18: Error: Method not found: 'Bar'.
+  var y = prefix.Bar();
+                 ^^^", "pkg/front_end/testcases/implicit_new.dart:19:10: Error: Method not found: 'Bar'.
+  prefix.Bar();
+         ^^^"]/* from null */;
+static method testNSM() → dynamic {
+  dynamic y = throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Bar, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Bar, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+}
+static method f(dynamic x) → dynamic
+  return x;
+static method main() → dynamic {
+  self::Foo x = new self::Foo::•();
+  x = new self::Foo::•();
+  self::Bar z = new self::Bar::named();
+  z = new self::Bar::named();
+  self::f(new self::Foo::•());
+  self::f(new self::Foo::•());
+  self::f(new self::Bar::named());
+  self::f(new self::Bar::named());
+  core::List<core::Object> l = <core::Object>[new self::Foo::•(), new self::Bar::named()];
+  l = <core::Object>[new self::Foo::•(), new self::Bar::named()];
+  core::Map<core::String, core::Object> m = <core::String, core::Object>{"foo": new self::Foo::•(), "bar": new self::Bar::named()};
+  m = <core::String, core::Object>{"foo": new self::Foo::•(), "bar": new self::Bar::named()};
+  self::IndexTester i = new self::IndexTester::•();
+  i.{self::IndexTester::[]}(new self::Foo::•());
+  i.{self::IndexTester::[]}(new self::Foo::•());
+  i.{self::IndexTester::[]}(new self::Bar::named());
+  i.{self::IndexTester::[]}(new self::Bar::named());
+  i.{self::IndexTester::[]=}(new self::Foo::•(), null);
+  i.{self::IndexTester::[]=}(new self::Foo::•(), null);
+  i.{self::IndexTester::[]=}(new self::Bar::named(), null);
+  i.{self::IndexTester::[]=}(new self::Bar::named(), null);
+  new self::Foo::•().{self::Foo::+}(new self::Bar::named());
+  new self::Foo::•().{self::Foo::+}(new self::Bar::named());
+  new self::Bar::named().{self::Bar::+}(new self::Foo::•());
+  new self::Bar::named().{self::Bar::+}(new self::Foo::•());
+}
diff --git a/pkg/front_end/testcases/implicit_scope_test.dart.direct.transformed.expect b/pkg/front_end/testcases/implicit_scope_test.dart.direct.transformed.expect
new file mode 100644
index 0000000..ef5e29a
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.direct.transformed.expect
@@ -0,0 +1,47 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+class ImplicitScopeTest extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method alwaysTrue() → core::bool {
+    return 1.+(1).==(2);
+  }
+  static method testMain() → dynamic {
+    dynamic a = "foo";
+    dynamic b;
+    if(self::ImplicitScopeTest::alwaysTrue()) {
+      dynamic a = "bar";
+    }
+    else {
+      dynamic b = a;
+    }
+    exp::Expect::equals("foo", a);
+    exp::Expect::equals(null, b);
+    while (!self::ImplicitScopeTest::alwaysTrue()) {
+      dynamic a = "bar";
+      dynamic b = "baz";
+    }
+    exp::Expect::equals("foo", a);
+    exp::Expect::equals(null, b);
+    for (core::int i = 0; i.<(10); i = i.+(1)) {
+      dynamic a = "bar";
+      dynamic b = "baz";
+    }
+    exp::Expect::equals("foo", a);
+    exp::Expect::equals(null, b);
+    do {
+      dynamic a = "bar";
+      dynamic b = "baz";
+    }
+    while ("black".==("white"))
+    exp::Expect::equals("foo", a);
+    exp::Expect::equals(null, b);
+  }
+}
+static method main() → dynamic {
+  self::ImplicitScopeTest::testMain();
+}
diff --git a/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect b/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect
new file mode 100644
index 0000000..9ac1d76
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_scope_test.dart.strong.transformed.expect
@@ -0,0 +1,47 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+class ImplicitScopeTest extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method alwaysTrue() → core::bool {
+    return 1.{core::num::+}(1).{core::num::==}(2);
+  }
+  static method testMain() → dynamic {
+    core::String a = "foo";
+    dynamic b;
+    if(self::ImplicitScopeTest::alwaysTrue()) {
+      dynamic a = "bar";
+    }
+    else {
+      dynamic b = a;
+    }
+    exp::Expect::equals("foo", a);
+    exp::Expect::equals(null, b);
+    while (!self::ImplicitScopeTest::alwaysTrue()) {
+      dynamic a = "bar";
+      dynamic b = "baz";
+    }
+    exp::Expect::equals("foo", a);
+    exp::Expect::equals(null, b);
+    for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+      dynamic a = "bar";
+      dynamic b = "baz";
+    }
+    exp::Expect::equals("foo", a);
+    exp::Expect::equals(null, b);
+    do {
+      dynamic a = "bar";
+      dynamic b = "baz";
+    }
+    while ("black".{core::String::==}("white"))
+    exp::Expect::equals("foo", a);
+    exp::Expect::equals(null, b);
+  }
+}
+static method main() → dynamic {
+  self::ImplicitScopeTest::testMain();
+}
diff --git a/pkg/front_end/testcases/implicit_this.dart.direct.transformed.expect b/pkg/front_end/testcases/implicit_this.dart.direct.transformed.expect
new file mode 100644
index 0000000..a599fbe
--- /dev/null
+++ b/pkg/front_end/testcases/implicit_this.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic {
+    core::print("Called m");
+  }
+  method testC() → dynamic {
+    this.{self::C::m}();
+  }
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method testD() → dynamic {
+    this.{self::C::m}();
+  }
+}
+static method main() → dynamic {
+  new self::C::•().testC();
+  new self::D::•().testD();
+}
diff --git a/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.direct.transformed.expect
new file mode 100644
index 0000000..3cd8d21
--- /dev/null
+++ b/pkg/front_end/testcases/inference/abstract_class_instantiation.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class D<T extends core::Object> extends core::Object {
+  constructor •(self::D::T t) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  dynamic x = throw new core::AbstractClassInstantiationError::•("C");
+  dynamic y = let final dynamic #t1 = 1 in throw new core::AbstractClassInstantiationError::•("D");
+  self::D<core::List<core::int>> z = let final dynamic #t2 = <dynamic>[] in throw new core::AbstractClassInstantiationError::•("D");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/assert.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/assert.dart.direct.transformed.expect
new file mode 100644
index 0000000..e5a1b8f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  assert(self::f<dynamic>());
+  assert(self::f<dynamic>(), self::f<dynamic>());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/assert.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/assert.dart.strong.transformed.expect
new file mode 100644
index 0000000..004b776
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  assert(self::f<core::bool>());
+  assert(self::f<core::bool>(), self::f<dynamic>());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/assert_initializer.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/assert_initializer.dart.direct.transformed.expect
new file mode 100644
index 0000000..602da12
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert_initializer.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor expressionOnly() → void
+    : assert(self::f<dynamic>()), super core::Object::•()
+    ;
+  constructor expressionAndMessage() → void
+    : assert(self::f<dynamic>(), self::f<dynamic>()), super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {
+  assert(self::f<dynamic>());
+  assert(self::f<dynamic>(), self::f<dynamic>());
+}
diff --git a/pkg/front_end/testcases/inference/assert_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/assert_initializer.dart.strong.transformed.expect
new file mode 100644
index 0000000..27f0c32
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assert_initializer.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor expressionOnly() → void
+    : assert(self::f<core::bool>()), super core::Object::•()
+    ;
+  constructor expressionAndMessage() → void
+    : assert(self::f<core::bool>(), self::f<dynamic>()), super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {
+  assert(self::f<core::bool>());
+  assert(self::f<core::bool>(), self::f<dynamic>());
+}
diff --git a/pkg/front_end/testcases/inference/assign_local.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/assign_local.dart.direct.transformed.expect
new file mode 100644
index 0000000..92719ee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assign_local.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::Object> extends self::A<self::B::T> {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {
+  core::num x;
+  dynamic x1 = x = 1;
+  dynamic x2 = x = 1.0;
+  self::A<core::int> y;
+  dynamic y1 = y = new self::A::•<dynamic>();
+  dynamic y2 = y = new self::B::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/inference/assign_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/assign_local.dart.strong.transformed.expect
new file mode 100644
index 0000000..e8e11fe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/assign_local.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::Object> extends self::A<self::B::T> {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {
+  core::num x;
+  core::int x1 = x = 1;
+  core::double x2 = x = 1.0;
+  self::A<core::int> y;
+  self::A<core::int> y1 = y = new self::A::•<core::int>();
+  self::B<core::int> y2 = y = new self::B::•<core::int>();
+}
diff --git a/pkg/front_end/testcases/inference/async_await.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/async_await.dart.direct.transformed.expect
new file mode 100644
index 0000000..40299a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_await.dart.direct.transformed.expect
@@ -0,0 +1,337 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+abstract class MyFuture extends core::Object implements asy::Future<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        core::int x0;
+        asy::Future<core::int> x1;
+        asy::Future<asy::Future<core::int>> x2;
+        asy::Future<asy::FutureOr<core::int>> x3;
+        asy::Future<self::MyFuture> x4;
+        asy::FutureOr<core::int> x5;
+        asy::FutureOr<asy::Future<core::int>> x6;
+        asy::FutureOr<asy::FutureOr<core::int>> x7;
+        asy::FutureOr<self::MyFuture> x8;
+        self::MyFuture x9;
+        function test0() → dynamic /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L2:
+              {
+                :return_value = x0;
+                break #L2;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test1() → dynamic /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L3:
+              {
+                :return_value = x1;
+                break #L3;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test2() → dynamic /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L4:
+              {
+                :return_value = x2;
+                break #L4;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test3() → dynamic /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L5:
+              {
+                :return_value = x3;
+                break #L5;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test4() → dynamic /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L6:
+              {
+                :return_value = x4;
+                break #L6;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test5() → dynamic /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L7:
+              {
+                :return_value = x5;
+                break #L7;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test6() → dynamic /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L8:
+              {
+                :return_value = x6;
+                break #L8;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test7() → dynamic /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L9:
+              {
+                :return_value = x7;
+                break #L9;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test8() → dynamic /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L10:
+              {
+                :return_value = x8;
+                break #L10;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test9() → dynamic /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L11:
+              {
+                :return_value = x9;
+                break #L11;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        [yield] let dynamic #t1 = asy::_awaitHelper(x0, :async_op_then, :async_op_error, :async_op) in null;
+        dynamic y0 = :result;
+        [yield] let dynamic #t2 = asy::_awaitHelper(x1, :async_op_then, :async_op_error, :async_op) in null;
+        dynamic y1 = :result;
+        [yield] let dynamic #t3 = asy::_awaitHelper(x2, :async_op_then, :async_op_error, :async_op) in null;
+        dynamic y2 = :result;
+        [yield] let dynamic #t4 = asy::_awaitHelper(x3, :async_op_then, :async_op_error, :async_op) in null;
+        dynamic y3 = :result;
+        [yield] let dynamic #t5 = asy::_awaitHelper(x4, :async_op_then, :async_op_error, :async_op) in null;
+        dynamic y4 = :result;
+        [yield] let dynamic #t6 = asy::_awaitHelper(x5, :async_op_then, :async_op_error, :async_op) in null;
+        dynamic y5 = :result;
+        [yield] let dynamic #t7 = asy::_awaitHelper(x6, :async_op_then, :async_op_error, :async_op) in null;
+        dynamic y6 = :result;
+        [yield] let dynamic #t8 = asy::_awaitHelper(x7, :async_op_then, :async_op_error, :async_op) in null;
+        dynamic y7 = :result;
+        [yield] let dynamic #t9 = asy::_awaitHelper(x8, :async_op_then, :async_op_error, :async_op) in null;
+        dynamic y8 = :result;
+        [yield] let dynamic #t10 = asy::_awaitHelper(x9, :async_op_then, :async_op_error, :async_op) in null;
+        dynamic y9 = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
new file mode 100644
index 0000000..0c4ef21
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
@@ -0,0 +1,338 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+abstract class MyFuture extends core::Object implements asy::Future<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub method timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<core::int> onTimeout}) → asy::Future<core::int>;
+}
+static method test() → void /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        core::int x0;
+        asy::Future<core::int> x1;
+        asy::Future<asy::Future<core::int>> x2;
+        asy::Future<asy::FutureOr<core::int>> x3;
+        asy::Future<self::MyFuture> x4;
+        asy::FutureOr<core::int> x5;
+        asy::FutureOr<asy::Future<core::int>> x6;
+        asy::FutureOr<asy::FutureOr<core::int>> x7;
+        asy::FutureOr<self::MyFuture> x8;
+        self::MyFuture x9;
+        function test0() → asy::Future<core::int> /* originally async */ {
+          final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+          asy::FutureOr<core::int> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L2:
+              {
+                :return_value = x0;
+                break #L2;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test1() → asy::Future<core::int> /* originally async */ {
+          final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+          asy::FutureOr<core::int> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L3:
+              {
+                :return_value = x1;
+                break #L3;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test2() → asy::Future<asy::Future<core::int>> /* originally async */ {
+          final asy::Completer<asy::Future<core::int>> :completer = asy::Completer::sync<asy::Future<core::int>>();
+          asy::FutureOr<asy::Future<core::int>> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L4:
+              {
+                :return_value = x2;
+                break #L4;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test3() → asy::Future<asy::FutureOr<core::int>> /* originally async */ {
+          final asy::Completer<asy::FutureOr<core::int>> :completer = asy::Completer::sync<asy::FutureOr<core::int>>();
+          asy::FutureOr<asy::FutureOr<core::int>> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L5:
+              {
+                :return_value = x3;
+                break #L5;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test4() → asy::Future<self::MyFuture> /* originally async */ {
+          final asy::Completer<self::MyFuture> :completer = asy::Completer::sync<self::MyFuture>();
+          asy::FutureOr<self::MyFuture> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L6:
+              {
+                :return_value = x4;
+                break #L6;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test5() → asy::Future<core::int> /* originally async */ {
+          final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+          asy::FutureOr<core::int> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L7:
+              {
+                :return_value = x5;
+                break #L7;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test6() → asy::Future<asy::Future<core::int>> /* originally async */ {
+          final asy::Completer<asy::Future<core::int>> :completer = asy::Completer::sync<asy::Future<core::int>>();
+          asy::FutureOr<asy::Future<core::int>> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L8:
+              {
+                :return_value = x6;
+                break #L8;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test7() → asy::Future<asy::FutureOr<core::int>> /* originally async */ {
+          final asy::Completer<asy::FutureOr<core::int>> :completer = asy::Completer::sync<asy::FutureOr<core::int>>();
+          asy::FutureOr<asy::FutureOr<core::int>> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L9:
+              {
+                :return_value = x7;
+                break #L9;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test8() → asy::Future<self::MyFuture> /* originally async */ {
+          final asy::Completer<self::MyFuture> :completer = asy::Completer::sync<self::MyFuture>();
+          asy::FutureOr<self::MyFuture> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L10:
+              {
+                :return_value = x8;
+                break #L10;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        function test9() → asy::Future<core::int> /* originally async */ {
+          final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+          asy::FutureOr<core::int> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L11:
+              {
+                :return_value = x9;
+                break #L11;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        }
+        [yield] let dynamic #t1 = asy::_awaitHelper(x0, :async_op_then, :async_op_error, :async_op) in null;
+        core::int y0 = :result;
+        [yield] let dynamic #t2 = asy::_awaitHelper(x1, :async_op_then, :async_op_error, :async_op) in null;
+        core::int y1 = :result;
+        [yield] let dynamic #t3 = asy::_awaitHelper(x2, :async_op_then, :async_op_error, :async_op) in null;
+        asy::Future<core::int> y2 = :result;
+        [yield] let dynamic #t4 = asy::_awaitHelper(x3, :async_op_then, :async_op_error, :async_op) in null;
+        asy::FutureOr<core::int> y3 = :result;
+        [yield] let dynamic #t5 = asy::_awaitHelper(x4, :async_op_then, :async_op_error, :async_op) in null;
+        self::MyFuture y4 = :result;
+        [yield] let dynamic #t6 = asy::_awaitHelper(x5, :async_op_then, :async_op_error, :async_op) in null;
+        core::int y5 = :result;
+        [yield] let dynamic #t7 = asy::_awaitHelper(x6, :async_op_then, :async_op_error, :async_op) in null;
+        asy::Future<core::int> y6 = :result;
+        [yield] let dynamic #t8 = asy::_awaitHelper(x7, :async_op_then, :async_op_error, :async_op) in null;
+        asy::FutureOr<core::int> y7 = :result;
+        [yield] let dynamic #t9 = asy::_awaitHelper(x8, :async_op_then, :async_op_error, :async_op) in null;
+        self::MyFuture y8 = :result;
+        [yield] let dynamic #t10 = asy::_awaitHelper(x9, :async_op_then, :async_op_error, :async_op) in null;
+        core::int y9 = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.direct.transformed.expect
new file mode 100644
index 0000000..a111519
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.direct.transformed.expect
@@ -0,0 +1,38 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static field asy::Future<core::int> futureInt = null;
+static field dynamic f = () → dynamic => self::futureInt;
+static field dynamic g = () → asy::Future<dynamic> /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = self::futureInt;
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+};
+static method main() → dynamic {
+  self::f;
+  self::g;
+}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
new file mode 100644
index 0000000..a6aca80
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static field asy::Future<core::int> futureInt = null;
+static field () → asy::Future<core::int> f = () → asy::Future<core::int> => self::futureInt;
+static field () → asy::Future<core::int> g = () → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = self::futureInt;
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+};
+static method main() → dynamic {
+  self::f;
+  self::g;
+}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.direct.transformed.expect
new file mode 100644
index 0000000..4bf2eb0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+
+static field dynamic f = () → asy::Future<dynamic> /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = 0;
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+};
+static method main() → dynamic {
+  self::f;
+}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
new file mode 100644
index 0000000..5af9546
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static field () → asy::Future<core::int> f = () → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = 0;
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+};
+static method main() → dynamic {
+  self::f;
+}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.direct.transformed.expect
new file mode 100644
index 0000000..7702de6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.direct.transformed.expect
@@ -0,0 +1,38 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static field asy::FutureOr<core::int> futureOrInt = null;
+static field dynamic f = () → dynamic => self::futureOrInt;
+static field dynamic g = () → asy::Future<dynamic> /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = self::futureOrInt;
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+};
+static method main() → dynamic {
+  self::f;
+  self::g;
+}
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
new file mode 100644
index 0000000..f49a5d2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static field asy::FutureOr<core::int> futureOrInt = null;
+static field () → asy::FutureOr<core::int> f = () → asy::FutureOr<core::int> => self::futureOrInt;
+static field () → asy::Future<core::int> g = () → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = self::futureOrInt;
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+};
+static method main() → dynamic {
+  self::f;
+  self::g;
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.direct.transformed.expect
new file mode 100644
index 0000000..ae1ed7a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.direct.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:math" as math;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  dynamic f = () → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(math::Random::•().nextBool()) {
+            :return_value = asy::Future::value<core::int>(1);
+            break #L1;
+          }
+          else {
+            :return_value = asy::Future::value<core::double>(2.0);
+            break #L1;
+          }
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  };
+  asy::Future<core::num> g = f.call();
+  asy::Future<core::int> h = f.call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
new file mode 100644
index 0000000..649f426
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+import "dart:math" as math;
+
+static method test() → dynamic {
+  () → asy::Future<core::num> f = () → asy::Future<core::num> /* originally async */ {
+    final asy::Completer<core::num> :completer = asy::Completer::sync<core::num>();
+    asy::FutureOr<core::num> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(math::Random::•().{math::Random::nextBool}()) {
+            :return_value = asy::Future::value<core::int>(1);
+            break #L1;
+          }
+          else {
+            :return_value = asy::Future::value<core::double>(2.0);
+            break #L1;
+          }
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  };
+  asy::Future<core::num> g = f.call();
+  asy::Future<core::int> h = f.call() as{TypeError} asy::Future<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.direct.transformed.expect
new file mode 100644
index 0000000..93b15b0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.direct.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:math" as math;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  dynamic f = () → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(math::Random::•().nextBool()) {
+            :return_value = 1;
+            break #L1;
+          }
+          else {
+            :return_value = 2.0;
+            break #L1;
+          }
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  };
+  asy::Future<core::num> g = f.call();
+  asy::Future<core::int> h = f.call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
new file mode 100644
index 0000000..97e2f95
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+import "dart:math" as math;
+
+static method test() → dynamic {
+  () → asy::Future<core::num> f = () → asy::Future<core::num> /* originally async */ {
+    final asy::Completer<core::num> :completer = asy::Completer::sync<core::num>();
+    asy::FutureOr<core::num> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(math::Random::•().{math::Random::nextBool}()) {
+            :return_value = 1;
+            break #L1;
+          }
+          else {
+            :return_value = 2.0;
+            break #L1;
+          }
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  };
+  asy::Future<core::num> g = f.call();
+  asy::Future<core::int> h = f.call() as{TypeError} asy::Future<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.direct.transformed.expect
new file mode 100644
index 0000000..8c968ee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.direct.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:math" as math;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  dynamic f = () → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(math::Random::•().nextBool()) {
+            :return_value = asy::Future::value<core::int>(1);
+            break #L1;
+          }
+          else {
+            :return_value = 2.0;
+            break #L1;
+          }
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  };
+  asy::Future<core::num> g = f.call();
+  asy::Future<core::int> h = f.call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
new file mode 100644
index 0000000..45d5637
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+import "dart:math" as math;
+
+static method test() → dynamic {
+  () → asy::Future<core::num> f = () → asy::Future<core::num> /* originally async */ {
+    final asy::Completer<core::num> :completer = asy::Completer::sync<core::num>();
+    asy::FutureOr<core::num> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(math::Random::•().{math::Random::nextBool}()) {
+            :return_value = asy::Future::value<core::int>(1);
+            break #L1;
+          }
+          else {
+            :return_value = 2.0;
+            break #L1;
+          }
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  };
+  asy::Future<core::num> g = f.call();
+  asy::Future<core::int> h = f.call() as{TypeError} asy::Future<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.direct.transformed.expect
new file mode 100644
index 0000000..c8ab798
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.direct.transformed.expect
@@ -0,0 +1,48 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  dynamic f = () → asy::Stream<dynamic> /* originally async* */ {
+    asy::_AsyncStarStreamController<dynamic> :controller;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try
+        try {
+          #L1:
+          {
+            if(:controller.{asy::_AsyncStarStreamController::add}(1))
+              return null;
+            else
+              [yield] null;
+            asy::Stream<core::double> s;
+            if(:controller.{asy::_AsyncStarStreamController::addStream}(s))
+              return null;
+            else
+              [yield] null;
+          }
+          return;
+        }
+        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+          :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+        }
+      finally {
+        :controller.{asy::_AsyncStarStreamController::close}();
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+    return :controller.{asy::_AsyncStarStreamController::stream};
+  };
+  asy::Stream<core::num> g = f.call();
+  asy::Stream<core::int> h = f.call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect
new file mode 100644
index 0000000..d13756d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_star.dart.strong.transformed.expect
@@ -0,0 +1,48 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  () → asy::Stream<core::num> f = () → asy::Stream<core::num> /* originally async* */ {
+    asy::_AsyncStarStreamController<core::num> :controller;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try
+        try {
+          #L1:
+          {
+            if(:controller.{asy::_AsyncStarStreamController::add}(1))
+              return null;
+            else
+              [yield] null;
+            asy::Stream<core::double> s;
+            if(:controller.{asy::_AsyncStarStreamController::addStream}(s))
+              return null;
+            else
+              [yield] null;
+          }
+          return;
+        }
+        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+          :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+        }
+      finally {
+        :controller.{asy::_AsyncStarStreamController::close}();
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :controller = new asy::_AsyncStarStreamController::•<core::num>(:async_op);
+    return :controller.{asy::_AsyncStarStreamController::stream};
+  };
+  asy::Stream<core::num> g = f.call();
+  asy::Stream<core::int> h = f.call() as{TypeError} asy::Stream<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.direct.transformed.expect
new file mode 100644
index 0000000..aeecf2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::List<core::int> o;
+  dynamic y = o.map((dynamic x) → dynamic {
+    return x.+(1);
+  });
+  core::Iterable<core::int> z = y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.strong.transformed.expect
new file mode 100644
index 0000000..e5bcf8f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::List<core::int> o;
+  core::Iterable<core::int> y = o.{core::Iterable::map}<core::int>((core::int x) → core::int {
+    return x.{core::num::+}(1);
+  });
+  core::Iterable<core::int> z = y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.direct.transformed.expect
new file mode 100644
index 0000000..6a30de0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f() → dynamic {
+  core::List<core::int> o;
+  o.where((dynamic i) → dynamic {
+    return i.==(0);
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.strong.transformed.expect
new file mode 100644
index 0000000..86aa2ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_basic_void.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f() → dynamic {
+  core::List<core::int> o;
+  o.{core::Iterable::where}((core::int i) → core::bool {
+    return i.{core::num::==}(0);
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.direct.transformed.expect
new file mode 100644
index 0000000..5c8ecc1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  function f() → core::String
+    return null;
+  dynamic g = f;
+  g = () → dynamic {
+    return 1;
+  };
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..33fd7df
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  function f() → core::String
+    return null;
+  () → core::String g = f;
+  g = () → core::String {
+    return let final core::int #t1 = 1 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference.dart:12:45: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+    return /*error:RETURN_OF_INVALID_TYPE*/ 1;
+                                            ^";
+  };
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.direct.transformed.expect
new file mode 100644
index 0000000..08eb46a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic g = self::f;
+static method f() → core::String
+  return null;
+static method main() → dynamic {
+  self::f;
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.strong.transformed.expect
new file mode 100644
index 0000000..3860922
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_downwards_incompatible_with_upwards_inference_top_level.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field () → core::String g = self::f;
+static method f() → core::String
+  return null;
+static method main() → dynamic {
+  self::f;
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.direct.transformed.expect
new file mode 100644
index 0000000..04b9dad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.direct.transformed.expect
@@ -0,0 +1,62 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        dynamic f = () → asy::Future<dynamic> /* originally async */ {
+          final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+          asy::FutureOr<dynamic> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L2:
+              {
+                :return_value = null;
+                break #L2;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        };
+        asy::Future<dynamic> y = f.call();
+        asy::Future<core::String> z = f.call();
+        [yield] let dynamic #t1 = asy::_awaitHelper(f.call(), :async_op_then, :async_op_error, :async_op) in null;
+        core::String s = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
new file mode 100644
index 0000000..1afc8d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        () → asy::Future<core::Null> f = () → asy::Future<core::Null> /* originally async */ {
+          final asy::Completer<core::Null> :completer = asy::Completer::sync<core::Null>();
+          asy::FutureOr<core::Null> :return_value;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try {
+              #L2:
+              {
+                :return_value = null;
+                break #L2;
+              }
+              :completer.{asy::Completer::complete}(:return_value);
+              return;
+            }
+            on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+              :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          asy::Future::microtask<dynamic>(:async_op);
+          return :completer.{asy::Completer::future};
+        };
+        asy::Future<dynamic> y = f.call();
+        asy::Future<core::String> z = f.call();
+        [yield] let dynamic #t1 = asy::_awaitHelper(f.call(), :async_op_then, :async_op_error, :async_op) in null;
+        core::String s = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.direct.transformed.expect
new file mode 100644
index 0000000..e58820a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.direct.transformed.expect
@@ -0,0 +1,68 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        dynamic f = () → asy::Stream<dynamic> /* originally async* */ {
+          asy::_AsyncStarStreamController<dynamic> :controller;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L2:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::add}(null))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+          return :controller.{asy::_AsyncStarStreamController::stream};
+        };
+        asy::Stream<dynamic> y = f.call();
+        asy::Stream<core::String> z = f.call();
+        [yield] let dynamic #t1 = asy::_awaitHelper(f.call().first, :async_op_then, :async_op_error, :async_op) in null;
+        core::String s = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
new file mode 100644
index 0000000..1d67b45
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
@@ -0,0 +1,68 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        () → asy::Stream<core::Null> f = () → asy::Stream<core::Null> /* originally async* */ {
+          asy::_AsyncStarStreamController<core::Null> :controller;
+          dynamic :async_stack_trace;
+          dynamic :async_op_then;
+          dynamic :async_op_error;
+          dynamic :await_jump_var = 0;
+          dynamic :await_ctx_var;
+          dynamic :saved_try_context_var0;
+          dynamic :saved_try_context_var1;
+          function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+            try
+              try {
+                #L2:
+                {
+                  if(:controller.{asy::_AsyncStarStreamController::add}(null))
+                    return null;
+                  else
+                    [yield] null;
+                }
+                return;
+              }
+              on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+                :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+              }
+            finally {
+              :controller.{asy::_AsyncStarStreamController::close}();
+            }
+          :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+          :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+          :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+          :controller = new asy::_AsyncStarStreamController::•<core::Null>(:async_op);
+          return :controller.{asy::_AsyncStarStreamController::stream};
+        };
+        asy::Stream<dynamic> y = f.call();
+        asy::Stream<core::String> z = f.call();
+        [yield] let dynamic #t1 = asy::_awaitHelper(f.call().{asy::Stream::first}, :async_op_then, :async_op_error, :async_op) in null;
+        core::String s = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.direct.transformed.expect
new file mode 100644
index 0000000..3287dd0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic h = null;
+static method foo((core::Object) → core::int f) → void {}
+static method test() → dynamic {
+  dynamic f = (core::Object x) → dynamic {
+    return null;
+  };
+  core::String y = f.call(42);
+  f = (dynamic x) → dynamic => "hello";
+  self::foo((dynamic x) → dynamic {
+    return null;
+  });
+  self::foo((dynamic x) → dynamic {
+    throw "not implemented";
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.transformed.expect
new file mode 100644
index 0000000..ffc9a26
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic h = null;
+static method foo((core::Object) → core::int f) → void {}
+static method test() → dynamic {
+  (core::Object) → core::Null f = (core::Object x) → core::Null {
+    return null;
+  };
+  core::String y = f.call(42);
+  f = (core::Object x) → core::Null => "hello" as{TypeError} core::Null;
+  self::foo((core::Object x) → core::Null {
+    return null;
+  });
+  self::foo((core::Object x) → core::Null {
+    throw "not implemented";
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.direct.transformed.expect
new file mode 100644
index 0000000..f1c2713
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  dynamic f = () → core::Iterable<dynamic> /* originally sync* */ {
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :sync_op(core::_SyncIterator<dynamic> :iterator) → core::bool yielding {
+      {
+        {
+          :iterator.{core::_SyncIterator::_current} = null;
+          [yield] true;
+        }
+      }
+      return false;
+    }
+    return new core::_SyncIterable::•<dynamic>(:sync_op);
+  };
+  core::Iterable<dynamic> y = f.call();
+  core::Iterable<core::String> z = f.call();
+  core::String s = f.call().first;
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect
new file mode 100644
index 0000000..ef16872
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_sync_star.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  () → core::Iterable<core::Null> f = () → core::Iterable<core::Null> /* originally sync* */ {
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :sync_op(core::_SyncIterator<core::Null> :iterator) → core::bool yielding {
+      {
+        {
+          :iterator.{core::_SyncIterator::_current} = null;
+          [yield] true;
+        }
+      }
+      return false;
+    }
+    return new core::_SyncIterable::•<core::Null>(:sync_op);
+  };
+  core::Iterable<dynamic> y = f.call();
+  core::Iterable<core::String> z = f.call();
+  core::String s = f.call().{core::Iterable::first};
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.direct.transformed.expect
new file mode 100644
index 0000000..3f1899b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+
+static method test2() → dynamic {
+  core::List<core::num> o;
+  dynamic y = o.map((dynamic x) → dynamic {
+    if(math::Random::•().nextBool()) {
+      return x.toInt().+(1);
+    }
+    else {
+      return x.toDouble();
+    }
+  });
+  core::Iterable<core::num> w = y;
+  core::Iterable<core::int> z = y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.transformed.expect
new file mode 100644
index 0000000..6c27cd0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_lub.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+
+static method test2() → dynamic {
+  core::List<core::num> o;
+  core::Iterable<core::num> y = o.{core::Iterable::map}<core::num>((core::num x) → core::num {
+    if(math::Random::•().{math::Random::nextBool}()) {
+      return x.{core::num::toInt}().{core::num::+}(1);
+    }
+    else {
+      return x.{core::num::toDouble}();
+    }
+  });
+  core::Iterable<core::num> w = y;
+  core::Iterable<core::int> z = y as{TypeError} core::Iterable<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.direct.transformed.expect
new file mode 100644
index 0000000..c435423
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  dynamic f = () → dynamic {
+    return (core::int x) → dynamic {
+      return 2.0.*(x);
+    };
+  };
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.strong.transformed.expect
new file mode 100644
index 0000000..1939518
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_nested_lambdas.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  () → (core::int) → core::double f = () → (core::int) → core::double {
+    return (core::int x) → core::double {
+      return 2.0.{core::double::*}(x);
+    };
+  };
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.direct.transformed.expect
new file mode 100644
index 0000000..e318418
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::List<core::int> o;
+  dynamic y = o.map((dynamic x) → dynamic {});
+  core::Iterable<core::int> z = y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.transformed.expect
new file mode 100644
index 0000000..c8d8caa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_no_return.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::List<core::int> o;
+  core::Iterable<core::Null> y = o.{core::Iterable::map}<core::Null>((core::int x) → core::Null {});
+  core::Iterable<core::int> z = y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.direct.transformed.expect
new file mode 100644
index 0000000..895ff01
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.direct.transformed.expect
@@ -0,0 +1,88 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  dynamic a = () → dynamic {};
+  dynamic b = () → dynamic {
+    return;
+  };
+  dynamic c = () → dynamic {
+    return null;
+  };
+  dynamic d = () → dynamic {
+    return 0;
+  };
+  dynamic e = (core::bool b) → dynamic {
+    if(b) {
+      return;
+    }
+    else {
+      return;
+    }
+  };
+  dynamic f = (core::bool b) → dynamic {
+    if(b) {
+      return;
+    }
+    else {
+      return null;
+    }
+  };
+  dynamic g = (core::bool b) → dynamic {
+    if(b) {
+      return;
+    }
+    else {
+      return 0;
+    }
+  };
+  dynamic h = (core::bool b) → dynamic {
+    if(b) {
+      return null;
+    }
+    else {
+      return;
+    }
+  };
+  dynamic i = (core::bool b) → dynamic {
+    if(b) {
+      return null;
+    }
+    else {
+      return null;
+    }
+  };
+  dynamic j = (core::bool b) → dynamic {
+    if(b) {
+      return null;
+    }
+    else {
+      return 0;
+    }
+  };
+  dynamic k = (core::bool b) → dynamic {
+    if(b) {
+      return 0;
+    }
+    else {
+      return;
+    }
+  };
+  dynamic l = (core::bool b) → dynamic {
+    if(b) {
+      return 0;
+    }
+    else {
+      return null;
+    }
+  };
+  dynamic m = (core::bool b) → dynamic {
+    if(b) {
+      return 0;
+    }
+    else {
+      return 0;
+    }
+  };
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect
new file mode 100644
index 0000000..b0ec67b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_returns.dart.strong.transformed.expect
@@ -0,0 +1,88 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  () → core::Null a = () → core::Null {};
+  () → core::Null b = () → core::Null {
+    return;
+  };
+  () → core::Null c = () → core::Null {
+    return null;
+  };
+  () → core::int d = () → core::int {
+    return 0;
+  };
+  (core::bool) → core::Null e = (core::bool b) → core::Null {
+    if(b) {
+      return;
+    }
+    else {
+      return;
+    }
+  };
+  (core::bool) → core::Null f = (core::bool b) → core::Null {
+    if(b) {
+      return;
+    }
+    else {
+      return null;
+    }
+  };
+  (core::bool) → core::int g = (core::bool b) → core::int {
+    if(b) {
+      return;
+    }
+    else {
+      return 0;
+    }
+  };
+  (core::bool) → core::Null h = (core::bool b) → core::Null {
+    if(b) {
+      return null;
+    }
+    else {
+      return;
+    }
+  };
+  (core::bool) → core::Null i = (core::bool b) → core::Null {
+    if(b) {
+      return null;
+    }
+    else {
+      return null;
+    }
+  };
+  (core::bool) → core::int j = (core::bool b) → core::int {
+    if(b) {
+      return null;
+    }
+    else {
+      return 0;
+    }
+  };
+  (core::bool) → core::int k = (core::bool b) → core::int {
+    if(b) {
+      return 0;
+    }
+    else {
+      return;
+    }
+  };
+  (core::bool) → core::int l = (core::bool b) → core::int {
+    if(b) {
+      return 0;
+    }
+    else {
+      return null;
+    }
+  };
+  (core::bool) → core::int m = (core::bool b) → core::int {
+    if(b) {
+      return 0;
+    }
+    else {
+      return 0;
+    }
+  };
+}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.direct.transformed.expect
new file mode 100644
index 0000000..8a11ab5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  dynamic f = () → core::Iterable<dynamic> /* originally sync* */ {
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :sync_op(core::_SyncIterator<dynamic> :iterator) → core::bool yielding {
+      {
+        {
+          :iterator.{core::_SyncIterator::_current} = 1;
+          [yield] true;
+        }
+        {
+          :iterator.{core::_SyncIterator::_yieldEachIterable} = <dynamic>[3, 4.0];
+          [yield] true;
+        }
+      }
+      return false;
+    }
+    return new core::_SyncIterable::•<dynamic>(:sync_op);
+  };
+  core::Iterable<core::num> g = f.call();
+  core::Iterable<core::int> h = f.call();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.strong.transformed.expect
new file mode 100644
index 0000000..bc47beb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_sync_star.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  () → core::Iterable<core::num> f = () → core::Iterable<core::num> /* originally sync* */ {
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :sync_op(core::_SyncIterator<core::num> :iterator) → core::bool yielding {
+      {
+        {
+          :iterator.{core::_SyncIterator::_current} = 1;
+          [yield] true;
+        }
+        {
+          :iterator.{core::_SyncIterator::_yieldEachIterable} = <core::num>[3, 4.0];
+          [yield] true;
+        }
+      }
+      return false;
+    }
+    return new core::_SyncIterable::•<core::num>(:sync_op);
+  };
+  core::Iterable<core::num> g = f.call();
+  core::Iterable<core::int> h = f.call() as{TypeError} core::Iterable<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.direct.transformed.expect
new file mode 100644
index 0000000..4273083
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f() → dynamic {
+  core::List<core::int> o;
+  o.forEach((dynamic i) → dynamic {
+    return i.+(1);
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.strong.transformed.expect
new file mode 100644
index 0000000..bdd35f6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_void_context.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f() → dynamic {
+  core::List<core::int> o;
+  o.{core::Iterable::forEach}((core::int i) → void {
+    return i.{core::num::+}(1);
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bottom.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bottom.dart.direct.transformed.expect
new file mode 100644
index 0000000..d841a5d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/bottom.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bottom.dart.strong.transformed.expect
new file mode 100644
index 0000000..d841a5d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/bottom_in_closure.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bottom_in_closure.dart.direct.transformed.expect
new file mode 100644
index 0000000..f08a258
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom_in_closure.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic v = () → dynamic => null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.transformed.expect
new file mode 100644
index 0000000..4ca225f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bottom_in_closure.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field () → core::Null v = () → core::Null => null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/bug30251.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bug30251.dart.direct.transformed.expect
new file mode 100644
index 0000000..fdfd49f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30251.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field dynamic x;
+  constructor •(core::int p) → void
+    : self::C::x = self::f<dynamic>(1.+(p)), super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>(self::f::T t) → self::f::T
+  return t;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bug30251.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug30251.dart.strong.transformed.expect
new file mode 100644
index 0000000..c3087fe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30251.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field dynamic x;
+  constructor •(core::int p) → void
+    : self::C::x = self::f<core::int>(1.{core::num::+}(p)), super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>(self::f::T t) → self::f::T
+  return t;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bug30620.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bug30620.dart.direct.transformed.expect
new file mode 100644
index 0000000..11677c0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::String foo;
+  constructor •(core::String foo) → void
+    : self::A::foo = foo, super core::Object::•()
+    ;
+  operator ==(core::Object other) → core::bool
+    return other is self::A && other{self::A}.foo.==(this.{self::A::foo});
+}
+static method main() → dynamic {
+  core::print(new self::A::•("hello").==(new self::A::•("hello")));
+}
diff --git a/pkg/front_end/testcases/inference/bug30620.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug30620.dart.strong.transformed.expect
new file mode 100644
index 0000000..b299931
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::String foo;
+  constructor •(core::String foo) → void
+    : self::A::foo = foo, super core::Object::•()
+    ;
+  operator ==(core::Object other) → core::bool
+    return other is self::A && other{self::A}.{self::A::foo}.{core::String::==}(this.{self::A::foo});
+}
+static method main() → dynamic {
+  core::print(new self::A::•("hello").{self::A::==}(new self::A::•("hello")));
+}
diff --git a/pkg/front_end/testcases/inference/bug30620_b.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bug30620_b.dart.direct.transformed.expect
new file mode 100644
index 0000000..35648da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_b.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::String foo;
+  constructor •(core::String foo) → void
+    : self::A::foo = foo, super core::Object::•()
+    ;
+  operator ==(core::Object other) → core::bool
+    return other is self::A && other{self::A}.foo.==(this.{self::A::foo}) && other{self::A}.foo.==(this.{self::A::foo});
+}
+static method main() → dynamic {
+  core::print(new self::A::•("hello").==(new self::A::•("hello")));
+}
diff --git a/pkg/front_end/testcases/inference/bug30620_b.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug30620_b.dart.strong.transformed.expect
new file mode 100644
index 0000000..ec87ef4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_b.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::String foo;
+  constructor •(core::String foo) → void
+    : self::A::foo = foo, super core::Object::•()
+    ;
+  operator ==(core::Object other) → core::bool
+    return other is self::A && other{self::A}.{self::A::foo}.{core::String::==}(this.{self::A::foo}) && other{self::A}.{self::A::foo}.{core::String::==}(this.{self::A::foo});
+}
+static method main() → dynamic {
+  core::print(new self::A::•("hello").{self::A::==}(new self::A::•("hello")));
+}
diff --git a/pkg/front_end/testcases/inference/bug30620_c.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bug30620_c.dart.direct.transformed.expect
new file mode 100644
index 0000000..239e30e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_c.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::String foo;
+  constructor •(core::String foo) → void
+    : self::A::foo = foo, super core::Object::•()
+    ;
+  operator ==(core::Object other) → core::bool {
+    if(other is self::A && other{self::A}.foo.==(this.{self::A::foo})) {
+      if(other{self::A}.foo.==(this.{self::A::foo})) {
+      }
+    }
+    return true;
+  }
+}
+static method main() → dynamic {
+  core::print(new self::A::•("hello").==(new self::A::•("hello")));
+}
diff --git a/pkg/front_end/testcases/inference/bug30620_c.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug30620_c.dart.strong.transformed.expect
new file mode 100644
index 0000000..4d95231
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_c.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::String foo;
+  constructor •(core::String foo) → void
+    : self::A::foo = foo, super core::Object::•()
+    ;
+  operator ==(core::Object other) → core::bool {
+    if(other is self::A && other{self::A}.{self::A::foo}.{core::String::==}(this.{self::A::foo})) {
+      if(other{self::A}.{self::A::foo}.{core::String::==}(this.{self::A::foo})) {
+      }
+    }
+    return true;
+  }
+}
+static method main() → dynamic {
+  core::print(new self::A::•("hello").{self::A::==}(new self::A::•("hello")));
+}
diff --git a/pkg/front_end/testcases/inference/bug30620_d.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bug30620_d.dart.direct.transformed.expect
new file mode 100644
index 0000000..1149d5f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_d.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method foo(dynamic obj) → core::String
+  return obj is core::String ? obj{core::String}.toUpperCase() : null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bug30620_d.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug30620_d.dart.strong.transformed.expect
new file mode 100644
index 0000000..39bc32b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30620_d.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method foo(dynamic obj) → core::String
+  return obj is core::String ?{core::String} obj{core::String}.{core::String::toUpperCase}() : null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bug30624.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bug30624.dart.direct.transformed.expect
new file mode 100644
index 0000000..9a75e22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30624.dart.direct.transformed.expect
@@ -0,0 +1,33 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<E extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method barA([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    self::foo<dynamic>(this, let final dynamic #t1 = cmp in #t1.==(null) ? self::C::_default : #t1);
+  }
+  method barB([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    self::foo<dynamic>(this, let final dynamic #t2 = cmp in #t2.==(null) ? self::C::_default as (self::C::E, self::C::E) → core::int : #t2);
+  }
+  method barC([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    (self::C::E, self::C::E) → core::int v = self::C::_default;
+    self::foo<dynamic>(this, let final dynamic #t3 = cmp in #t3.==(null) ? v : #t3);
+  }
+  method barD([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    self::foo<self::C::E>(this, let final dynamic #t4 = cmp in #t4.==(null) ? self::C::_default : #t4);
+  }
+  method barE([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    self::foo<dynamic>(this, cmp.==(null) ? self::C::_default : cmp);
+  }
+  method barF([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    self::foo<dynamic>(this, !cmp.==(null) ? cmp : self::C::_default);
+  }
+  static method _default(dynamic a, dynamic b) → core::int {
+    return 1.unary-();
+  }
+}
+static method foo<E extends core::Object>(self::C<self::foo::E> c, (self::foo::E, self::foo::E) → core::int cmp) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect
new file mode 100644
index 0000000..1f952f5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug30624.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<E extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method barA([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    self::foo<self::C::E>(this, let final (self::C::E, self::C::E) → core::int #t1 = cmp in #t1.==(null) ?{(self::C::E, self::C::E) → core::int} self::C::_default : #t1);
+  }
+  method barB([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    self::foo<self::C::E>(this, let final (self::C::E, self::C::E) → core::int #t2 = cmp in #t2.==(null) ?{(self::C::E, self::C::E) → core::int} self::C::_default as (self::C::E, self::C::E) → core::int : #t2);
+  }
+  method barC([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    (self::C::E, self::C::E) → core::int v = self::C::_default;
+    self::foo<self::C::E>(this, let final (self::C::E, self::C::E) → core::int #t3 = cmp in #t3.==(null) ?{(self::C::E, self::C::E) → core::int} v : #t3);
+  }
+  method barD([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    self::foo<self::C::E>(this, let final (self::C::E, self::C::E) → core::int #t4 = cmp in #t4.==(null) ?{(self::C::E, self::C::E) → core::int} self::C::_default : #t4);
+  }
+  method barE([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    self::foo<self::C::E>(this, cmp.{core::Object::==}(null) ?{(self::C::E, self::C::E) → core::int} self::C::_default : cmp);
+  }
+  method barF([(self::C::E, self::C::E) → core::int cmp = null]) → void {
+    self::foo<self::C::E>(this, !cmp.{core::Object::==}(null) ?{(self::C::E, self::C::E) → core::int} cmp : self::C::_default);
+  }
+  static method _default(dynamic a, dynamic b) → core::int {
+    return 1.{core::int::unary-}();
+  }
+}
+static method foo<E extends core::Object>(self::C<self::foo::E> c, (self::foo::E, self::foo::E) → core::int cmp) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bug31132.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bug31132.dart.direct.transformed.expect
new file mode 100644
index 0000000..29a4ab76
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31132.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends self::B {
+  field dynamic z = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method test(self::B x) → void {
+  dynamic y = x is self::C ? x{self::C} : new self::C::•();
+  core::print(y.z);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bug31132.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug31132.dart.strong.transformed.expect
new file mode 100644
index 0000000..0aa0ff6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31132.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends self::B {
+  field dynamic z = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method test(self::B x) → void {
+  self::C y = x is self::C ?{self::C} x{self::C} : new self::C::•();
+  core::print(y.{self::C::z});
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bug31133.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bug31133.dart.direct.transformed.expect
new file mode 100644
index 0000000..b2a0cef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31133.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+
+static method test() → void {
+  dynamic i = 0;
+  for (final dynamic #t1 = i = i.+(1); i.<(10); i = i.+(1)) {
+  }
+  for (final dynamic #t2 = i = i.+(1); i.<(10); i = i.+(1)) {
+  }
+  for (final dynamic #t3 = i = i.-(1); i.>=(0); i = i.-(1)) {
+  }
+  for (final dynamic #t4 = i = i.-(1); i.>=(0); i = i.-(1)) {
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bug31133.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug31133.dart.strong.transformed.expect
new file mode 100644
index 0000000..e333816
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31133.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::int i = 0;
+  for (final dynamic #t1 = i = i.{core::num::+}(1); i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+  }
+  for (final dynamic #t2 = i = i.{core::num::+}(1); i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+  }
+  for (final dynamic #t3 = i = i.{core::num::-}(1); i.{core::num::>=}(0); i = i.{core::num::-}(1)) {
+  }
+  for (final dynamic #t4 = i = i.{core::num::-}(1); i.{core::num::>=}(0); i = i.{core::num::-}(1)) {
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/bug31436.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bug31436.dart.direct.transformed.expect
new file mode 100644
index 0000000..e52bb02
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31436.dart.direct.transformed.expect
@@ -0,0 +1,74 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method block_test() → void {
+  () → core::List<core::Object> g;
+  g = () → dynamic {
+    return <dynamic>[3];
+  };
+  assert(g is () → core::List<core::Object>);
+  assert(!(g is () → core::List<core::int>));
+  g.call().add("hello");
+  core::List<core::int> l = <dynamic>[3];
+  g = () → dynamic {
+    return l;
+  };
+  assert(g is () → core::List<core::Object>);
+  assert(g is () → core::List<core::int>);
+  try {
+    g.call().add("hello");
+    throw "expected a runtime error";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+  core::Object o = l;
+  g = () → dynamic {
+    return o;
+  };
+  assert(g is () → core::List<core::Object>);
+  assert(!(g is () → core::List<core::int>));
+  assert(!(g is () → core::Object));
+  g.call();
+  o = 3;
+  try {
+    g.call();
+    throw "expected a runtime error";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method arrow_test() → void {
+  () → core::List<core::Object> g;
+  g = () → dynamic => <dynamic>[3];
+  assert(g is () → core::List<core::Object>);
+  assert(!(g is () → core::List<core::int>));
+  g.call().add("hello");
+  core::List<core::int> l = <dynamic>[3];
+  g = () → dynamic => l;
+  assert(g is () → core::List<core::Object>);
+  assert(g is () → core::List<core::int>);
+  try {
+    g.call().add("hello");
+    throw "expected a runtime error";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+  core::Object o = l;
+  g = () → dynamic => o;
+  assert(g is () → core::List<core::Object>);
+  assert(!(g is () → core::List<core::int>));
+  assert(!(g is () → core::Object));
+  g.call();
+  o = 3;
+  try {
+    g.call();
+    throw "expected a runtime error";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method main() → dynamic {
+  self::block_test();
+  self::arrow_test();
+}
diff --git a/pkg/front_end/testcases/inference/bug31436.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug31436.dart.strong.transformed.expect
new file mode 100644
index 0000000..1f2d373
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug31436.dart.strong.transformed.expect
@@ -0,0 +1,74 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method block_test() → void {
+  () → core::List<core::Object> g;
+  g = () → core::List<core::Object> {
+    return <core::Object>[3];
+  };
+  assert(g is () → core::List<core::Object>);
+  assert(!(g is () → core::List<core::int>));
+  g.call().{core::List::add}("hello");
+  core::List<core::int> l = <core::int>[3];
+  g = () → core::List<core::int> {
+    return l;
+  };
+  assert(g is () → core::List<core::Object>);
+  assert(g is () → core::List<core::int>);
+  try {
+    g.call().{core::List::add}("hello");
+    throw "expected a runtime error";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+  core::Object o = l;
+  g = () → core::List<core::Object> {
+    return o as{TypeError} core::List<core::Object>;
+  };
+  assert(g is () → core::List<core::Object>);
+  assert(!(g is () → core::List<core::int>));
+  assert(!(g is () → core::Object));
+  g.call();
+  o = 3;
+  try {
+    g.call();
+    throw "expected a runtime error";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method arrow_test() → void {
+  () → core::List<core::Object> g;
+  g = () → core::List<core::Object> => <core::Object>[3];
+  assert(g is () → core::List<core::Object>);
+  assert(!(g is () → core::List<core::int>));
+  g.call().{core::List::add}("hello");
+  core::List<core::int> l = <core::int>[3];
+  g = () → core::List<core::int> => l;
+  assert(g is () → core::List<core::Object>);
+  assert(g is () → core::List<core::int>);
+  try {
+    g.call().{core::List::add}("hello");
+    throw "expected a runtime error";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+  core::Object o = l;
+  g = () → core::List<core::Object> => o as{TypeError} core::List<core::Object>;
+  assert(g is () → core::List<core::Object>);
+  assert(!(g is () → core::List<core::int>));
+  assert(!(g is () → core::Object));
+  g.call();
+  o = 3;
+  try {
+    g.call();
+    throw "expected a runtime error";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method main() → dynamic {
+  self::block_test();
+  self::arrow_test();
+}
diff --git a/pkg/front_end/testcases/inference/bug32291.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/bug32291.dart.direct.transformed.expect
new file mode 100644
index 0000000..f2dc0b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug32291.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → void {
+  dynamic l = <dynamic>[<dynamic>["hi", "world"]];
+  dynamic i1 = l.map((dynamic ll) → dynamic => let final dynamic #t1 = ll in #t1.==(null) ? <dynamic>[] : #t1);
+  dynamic i2 = i1.map((core::List<core::String> l) → dynamic => l.length);
+  core::print(i2);
+}
diff --git a/pkg/front_end/testcases/inference/bug32291.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/bug32291.dart.strong.transformed.expect
new file mode 100644
index 0000000..6193515
--- /dev/null
+++ b/pkg/front_end/testcases/inference/bug32291.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → void {
+  core::List<core::List<core::String>> l = <core::List<core::String>>[<core::String>["hi", "world"]];
+  core::Iterable<core::List<core::String>> i1 = l.{core::Iterable::map}<core::List<core::String>>((core::List<core::String> ll) → core::List<core::String> => let final core::List<core::String> #t1 = ll in #t1.==(null) ?{core::List<core::String>} <core::String>[] : #t1);
+  core::Iterable<core::int> i2 = i1.{core::Iterable::map}<core::int>((core::List<core::String> l) → core::int => l.{core::List::length});
+  core::print(i2);
+}
diff --git a/pkg/front_end/testcases/inference/call_corner_cases.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/call_corner_cases.dart.direct.transformed.expect
new file mode 100644
index 0000000..8283021
--- /dev/null
+++ b/pkg/front_end/testcases/inference/call_corner_cases.dart.direct.transformed.expect
@@ -0,0 +1,36 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call() → core::int
+    return 0;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get call() → self::A
+    return new self::A::•();
+}
+class D extends core::Object {
+  field self::A fieldA = new self::A::•();
+  field self::B fieldB = new self::B::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get getA() → self::A
+    return new self::A::•();
+  get getB() → self::B
+    return new self::B::•();
+}
+static method main() → dynamic {
+  dynamic callA = new self::A::•().call();
+  dynamic callFieldA = new self::D::•().fieldA();
+  dynamic callGetA = new self::D::•().getA();
+  dynamic callFieldB = new self::D::•().fieldB();
+  dynamic callGetB = new self::D::•().getB();
+}
diff --git a/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.transformed.expect
new file mode 100644
index 0000000..6457f6f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/call_corner_cases.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call() → core::int
+    return 0;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get call() → self::A
+    return new self::A::•();
+}
+class D extends core::Object {
+  field self::A fieldA = new self::A::•();
+  field self::B fieldB = new self::B::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get getA() → self::A
+    return new self::A::•();
+  get getB() → self::B
+    return new self::B::•();
+}
+static method main() → dynamic {
+  core::int callA = new self::A::•().{self::A::call}();
+  core::int callFieldA = new self::D::•().{self::D::fieldA}();
+  core::int callGetA = new self::D::•().{self::D::getA}();
+  dynamic callFieldB = new self::D::•().{self::D::fieldB}();
+  dynamic callGetB = new self::D::•().{self::D::getB}();
+}
diff --git a/pkg/front_end/testcases/inference/callable_generic_class.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/callable_generic_class.dart.direct.transformed.expect
new file mode 100644
index 0000000..b1b2544
--- /dev/null
+++ b/pkg/front_end/testcases/inference/callable_generic_class.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class ActionDispatcher<P extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call([self::ActionDispatcher::P value = null]) → void {}
+}
+class Bar extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class FooActions extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get foo() → self::ActionDispatcher<self::Bar>
+    return new self::ActionDispatcher::•<self::Bar>();
+}
+static method main() → void {
+  new self::FooActions::•().foo(new self::Bar::•());
+  new self::FooActions::•().foo.call(new self::Bar::•());
+  new self::FooActions::•().foo.call(new self::Bar::•());
+}
diff --git a/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.transformed.expect
new file mode 100644
index 0000000..3e59656
--- /dev/null
+++ b/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class ActionDispatcher<P extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call([generic-covariant-impl generic-covariant-interface self::ActionDispatcher::P value = null]) → void {}
+}
+class Bar extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class FooActions extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get foo() → self::ActionDispatcher<self::Bar>
+    return new self::ActionDispatcher::•<self::Bar>();
+}
+static method main() → void {
+  new self::FooActions::•().{self::FooActions::foo}(new self::Bar::•());
+  new self::FooActions::•().{self::FooActions::foo}.{self::ActionDispatcher::call}(new self::Bar::•());
+  new self::FooActions::•().{self::FooActions::foo}.{self::ActionDispatcher::call}(new self::Bar::•());
+}
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.direct.transformed.expect
new file mode 100644
index 0000000..e22e2f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(dynamic x) → dynamic;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(dynamic x) → dynamic;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself via 'B'.
+abstract class A extends B {
+               ^", "pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself via 'A'.
+abstract class B extends A {
+               ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..e22e2f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_method_inference.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(dynamic x) → dynamic;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(dynamic x) → dynamic;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/circular_method_inference.dart:12:16: Error: 'A' is a supertype of itself via 'B'.
+abstract class A extends B {
+               ^", "pkg/front_end/testcases/inference/circular_method_inference.dart:16:16: Error: 'B' is a supertype of itself via 'A'.
+abstract class B extends A {
+               ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.direct.transformed.expect
new file mode 100644
index 0000000..fd3ef5e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library test;
+import self as self;
+
+static field dynamic x = () → dynamic => self::y;
+static field dynamic y = () → dynamic => self::x;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
new file mode 100644
index 0000000..56ef48b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+
+static field dynamic x = () → dynamic => self::y;
+static field dynamic y = () → dynamic => self::x;
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/circular_reference_via_closures.dart:10:67: Error: Can't infer the type of 'y': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
+                                                                  ^", "pkg/front_end/testcases/inference/circular_reference_via_closures.dart:8:67: Error: Can't infer the type of 'x': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
+                                                                  ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.direct.transformed.expect
new file mode 100644
index 0000000..fd3ef5e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library test;
+import self as self;
+
+static field dynamic x = () → dynamic => self::y;
+static field dynamic y = () → dynamic => self::x;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
new file mode 100644
index 0000000..8df972c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+
+static field dynamic x = () → dynamic => self::y;
+static field dynamic y = () → dynamic => self::x;
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:10:67: Error: Can't infer the type of 'y': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
+                                                                  ^", "pkg/front_end/testcases/inference/circular_reference_via_closures_initializer_types.dart:8:67: Error: Can't infer the type of 'x': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
+                                                                  ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.direct.transformed.expect
new file mode 100644
index 0000000..2a82c25
--- /dev/null
+++ b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  (core::Null) → core::int f = (dynamic x) → dynamic => 1;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.strong.transformed.expect
new file mode 100644
index 0000000..8bc94ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/closure_param_null_to_object.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  (core::Null) → core::int f = (core::Object x) → core::int => 1;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.direct.transformed.expect
new file mode 100644
index 0000000..a77c338
--- /dev/null
+++ b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+
+static method f() → dynamic {
+  dynamic a = 0;
+  dynamic b = null;
+  dynamic c = throw "foo";
+  dynamic d = () → dynamic => 0;
+  dynamic e = () → dynamic => null;
+  dynamic f = () → dynamic => throw "foo";
+  dynamic g = () → dynamic {
+    return 0;
+  };
+  dynamic h = () → dynamic {
+    return null;
+  };
+  dynamic i = () → dynamic {
+    return throw "foo";
+  };
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.transformed.expect
new file mode 100644
index 0000000..5f679a5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/coerce_bottom_and_null_types.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f() → dynamic {
+  core::int a = 0;
+  dynamic b = null;
+  dynamic c = throw "foo";
+  () → core::int d = () → core::int => 0;
+  () → core::Null e = () → core::Null => null;
+  () → <BottomType>f = () → <BottomType>=> throw "foo";
+  () → core::int g = () → core::int {
+    return 0;
+  };
+  () → core::Null h = () → core::Null {
+    return null;
+  };
+  () → <BottomType>i = () → <BottomType>{
+    return throw "foo";
+  };
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/complex_predecrement.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/complex_predecrement.dart.direct.transformed.expect
new file mode 100644
index 0000000..482fc82
--- /dev/null
+++ b/pkg/front_end/testcases/inference/complex_predecrement.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  dynamic foo = <dynamic>[1, 2, 3];
+  core::print(let final dynamic #t1 = foo in let final dynamic #t2 = 0 in let final dynamic #t3 = #t1.[](#t2).-(1) in let final dynamic #t4 = #t1.[]=(#t2, #t3) in #t3);
+}
diff --git a/pkg/front_end/testcases/inference/complex_predecrement.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/complex_predecrement.dart.strong.transformed.expect
new file mode 100644
index 0000000..4b3e283
--- /dev/null
+++ b/pkg/front_end/testcases/inference/complex_predecrement.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::List<core::int> foo = <core::int>[1, 2, 3];
+  core::print(let final core::List<core::int> #t1 = foo in let final core::int #t2 = 0 in let final core::int #t3 = #t1.{core::List::[]}(#t2).{core::num::-}(1) in let final void #t4 = #t1.{core::List::[]=}(#t2, #t3) in #t3);
+}
diff --git a/pkg/front_end/testcases/inference/conditional_lub.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/conditional_lub.dart.direct.transformed.expect
new file mode 100644
index 0000000..42ba544
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_lub.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::bool b = true;
+static field core::int x = 0;
+static field core::double y = 0.0;
+static field dynamic z = self::b ? self::x : self::y;
+static method main() → dynamic {
+  dynamic z = self::b ? self::x : self::y;
+}
diff --git a/pkg/front_end/testcases/inference/conditional_lub.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/conditional_lub.dart.strong.transformed.expect
new file mode 100644
index 0000000..2de4bbec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_lub.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::bool b = true;
+static field core::int x = 0;
+static field core::double y = 0.0;
+static field core::num z = self::b ?{core::num} self::x : self::y;
+static method main() → dynamic {
+  core::num z = self::b ?{core::num} self::x : self::y;
+}
diff --git a/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.direct.transformed.expect
new file mode 100644
index 0000000..8145e11
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor •(core::List<self::C::T> x) → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::bool b = false;
+  core::List<core::int> l1 = <dynamic>[1];
+  core::List<core::int> l2 = <dynamic>[2];
+  dynamic x = new self::C::•<dynamic>(l1);
+  dynamic y = new self::C::•<dynamic>(l2);
+  dynamic z = new self::C::•<dynamic>(b ? l1 : l2);
+}
diff --git a/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..a952ea0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conditional_upwards_inference.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor •(core::List<self::C::T> x) → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::bool b = false;
+  core::List<core::int> l1 = <core::int>[1];
+  core::List<core::int> l2 = <core::int>[2];
+  self::C<core::int> x = new self::C::•<core::int>(l1);
+  self::C<core::int> y = new self::C::•<core::int>(l2);
+  self::C<core::int> z = new self::C::•<core::int>(b ?{core::List<core::int>} l1 : l2);
+}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.direct.transformed.expect
new file mode 100644
index 0000000..569ad5d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen.dart.direct.transformed.expect
@@ -0,0 +1,43 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I1 extends core::Object {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class I2 extends self::I1 {
+  field core::int y = null;
+  synthetic constructor •() → void
+    : super self::I1::•()
+    ;
+}
+class A extends core::Object {
+  final field self::I1 a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  final field self::I2 a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C1 extends core::Object implements self::A, self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get a() → dynamic
+    return null;
+}
+class C2 extends core::Object implements self::B, self::A {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get a() → dynamic
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.direct.transformed.expect
new file mode 100644
index 0000000..a94ba90
--- /dev/null
+++ b/pkg/front_end/testcases/inference/conflicts_can_happen2.dart.direct.transformed.expect
@@ -0,0 +1,50 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I1 extends core::Object {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class I2 extends core::Object {
+  field core::int y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class I3 extends core::Object implements self::I1, self::I2 {
+  field core::int x = null;
+  field core::int y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  final field self::I1 a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  final field self::I2 a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C1 extends core::Object implements self::A, self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get a() → self::I3
+    return null;
+}
+class C2 extends core::Object implements self::A, self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get a() → dynamic
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.direct.transformed.expect
new file mode 100644
index 0000000..1def021
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class Foo<T extends self::A> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  self::Foo<self::B> foo = new self::Foo::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.strong.transformed.expect
new file mode 100644
index 0000000..4da3023
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_downwards_with_constraint.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class Foo<T extends self::A> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  self::Foo<self::B> foo = new self::Foo::•<self::B>();
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.direct.transformed.expect
new file mode 100644
index 0000000..8a1923c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  field self::C::T t;
+  constructor •(self::C::T t) → void
+    : self::C::t = t, super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  dynamic x = new self::C::•<dynamic>(42);
+  core::num y;
+  self::C<core::int> c_int = new self::C::•<dynamic>(y);
+  self::C<core::num> c_num = new self::C::•<dynamic>(123);
+  self::C<core::num> c_num2 = let final dynamic #t1 = new self::C::•<dynamic>(456) in let final dynamic #t2 = #t1.t = 1.0 in #t1;
+  dynamic c_dynamic = new self::C::•<dynamic>(42);
+  x.t = "hello";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
new file mode 100644
index 0000000..ac8f929
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T t;
+  constructor •(self::C::T t) → void
+    : self::C::t = t, super core::Object::•()
+    ;
+}
+static method test() → dynamic {
+  self::C<core::int> x = new self::C::•<core::int>(42);
+  core::num y;
+  self::C<core::int> c_int = new self::C::•<core::int>(y as{TypeError} core::int);
+  self::C<core::num> c_num = new self::C::•<core::num>(123);
+  self::C<core::num> c_num2 = let final self::C<core::num> #t1 = new self::C::•<core::num>(456) in let final core::double #t2 = #t1.{self::C::t} = 1.0 in #t1;
+  self::C<dynamic> c_dynamic = new self::C::•<dynamic>(42);
+  x.{self::C::t} = let final core::String #t3 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart:26:56: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+                                                       ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.direct.transformed.expect
new file mode 100644
index 0000000..619f0a3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_argument_not_assignable.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = () → T;
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<T extends self::A> extends core::Object {
+  constructor •(() → self::C::T f) → void
+    : super core::Object::•()
+    ;
+}
+class NotA extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method myF() → self::NotA
+  return null;
+static method main() → dynamic {
+  dynamic x = new self::C::•<dynamic>(self::myF);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.direct.transformed.expect
new file mode 100644
index 0000000..c3c0ebc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  final field self::C::T t;
+  const constructor •(self::C::T t) → void
+    : self::C::t = t, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic x = const self::C::•<dynamic>(42);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.strong.transformed.expect
new file mode 100644
index 0000000..366ee21
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  final field self::C::T t;
+  const constructor •(self::C::T t) → void
+    : self::C::t = t, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::C<core::int> x = const self::C::•<core::int>(42);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..f4cec98
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::num> extends core::Object {
+  final field self::C::T x;
+  const constructor •(self::C::T x) → void
+    : self::C::x = x, super core::Object::•()
+    ;
+}
+class D<T extends core::num> extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  const dynamic c = const self::C::•<dynamic>(0);
+  self::C<core::int> c2 = c;
+  const self::D<core::int> d = const self::D::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..97e2ca4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_const_with_upper_bound.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::num> extends core::Object {
+  final field self::C::T x;
+  const constructor •(self::C::T x) → void
+    : self::C::x = x, super core::Object::•()
+    ;
+}
+class D<T extends core::num> extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  const self::C<core::int> c = const self::C::•<core::int>(0);
+  self::C<core::int> c2 = c;
+  const self::D<core::int> d = const self::D::•<core::int>();
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.direct.transformed.expect
new file mode 100644
index 0000000..1e8e0c0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor •(core::List<self::C::T> list) → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic x = new self::C::•<dynamic>(<dynamic>[123]);
+  self::C<core::int> y = x;
+  dynamic a = new self::C::•<dynamic>(<dynamic>[123]);
+  dynamic b = new self::C::•<core::Object>(<dynamic>[123]);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.strong.transformed.expect
new file mode 100644
index 0000000..2950d68
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_downwards_from_constructor.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor •(core::List<self::C::T> list) → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::C<core::int> x = new self::C::•<core::int>(<core::int>[123]);
+  self::C<core::int> y = x;
+  self::C<dynamic> a = new self::C::•<dynamic>(<dynamic>[123]);
+  self::C<core::Object> b = new self::C::•<core::Object>(<core::Object>[123]);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.direct.transformed.expect
new file mode 100644
index 0000000..c9e1108
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  field self::C::T t = null;
+  constructor _() → void
+    : super core::Object::•()
+    ;
+  static factory •<T extends core::Object>(self::C::•::T t) → self::C<self::C::•::T> {
+    dynamic x = new self::C::_<self::C::•::T>();
+    x.t = t;
+    return x;
+  }
+}
+static method test() → dynamic {
+  dynamic x = self::C::•<dynamic>(42);
+  x.t = "hello";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
new file mode 100644
index 0000000..5d9e9d6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T t = null;
+  constructor _() → void
+    : super core::Object::•()
+    ;
+  static factory •<T extends core::Object>(self::C::•::T t) → self::C<self::C::•::T> {
+    self::C<self::C::•::T> x = new self::C::_<self::C::•::T>();
+    x.{self::C::t} = t;
+    return x;
+  }
+}
+static method test() → dynamic {
+  self::C<core::int> x = self::C::•<core::int>(42);
+  x.{self::C::t} = let final core::String #t1 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart:22:56: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x. /*@target=C::t*/ t = /*error:INVALID_ASSIGNMENT*/ 'hello';
+                                                       ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.direct.transformed.expect
new file mode 100644
index 0000000..538fd28
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  field self::A<self::A::T> f = new self::A::•<dynamic>();
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  static factory factory<T extends core::Object>() → self::A<self::A::factory::T>
+    return new self::A::•<dynamic>();
+  method m() → self::A<self::A::T>
+    return new self::A::•<dynamic>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.transformed.expect
new file mode 100644
index 0000000..ba0820f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::A<self::A::T> f = new self::A::•<self::A::T>();
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  static factory factory<T extends core::Object>() → self::A<self::A::factory::T>
+    return new self::A::•<self::A::factory::T>();
+  method m() → self::A<self::A::T>
+    return new self::A::•<self::A::T>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.direct.transformed.expect
new file mode 100644
index 0000000..f244bce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  field self::C::T t = null;
+  constructor named(core::List<self::C::T> t) → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic x = new self::C::named<dynamic>(<core::int>[]);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.transformed.expect
new file mode 100644
index 0000000..0e487ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T t = null;
+  constructor named(core::List<self::C::T> t) → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::C<core::int> x = new self::C::named<core::int>(<core::int>[]);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.direct.transformed.expect
new file mode 100644
index 0000000..b56ab2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  field self::C::T t = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  static factory named<T extends core::Object>(self::C::named::T t) → self::C<self::C::named::T> {
+    dynamic x = new self::C::•<self::C::named::T>();
+    x.t = t;
+    return x;
+  }
+}
+static method main() → dynamic {
+  dynamic x = self::C::named<dynamic>(42);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.transformed.expect
new file mode 100644
index 0000000..1b757b3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T t = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  static factory named<T extends core::Object>(self::C::named::T t) → self::C<self::C::named::T> {
+    self::C<self::C::named::T> x = new self::C::•<self::C::named::T>();
+    x.{self::C::t} = t;
+    return x;
+  }
+}
+static method main() → dynamic {
+  self::C<core::int> x = self::C::named<core::int>(42);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.direct.transformed.expect
new file mode 100644
index 0000000..41cb4fa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  field self::C::T t;
+  constructor •(self::C::T t) → void
+    : self::C::t = t, super core::Object::•()
+    ;
+  constructor named(core::List<self::C::T> t) → void
+    : this self::C::•(t.[](0))
+    ;
+}
+static method main() → dynamic {
+  dynamic x = new self::C::named<dynamic>(<core::int>[42]);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.transformed.expect
new file mode 100644
index 0000000..d250ca0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T t;
+  constructor •(self::C::T t) → void
+    : self::C::t = t, super core::Object::•()
+    ;
+  constructor named(core::List<self::C::T> t) → void
+    : this self::C::•(t.{core::List::[]}(0))
+    ;
+}
+static method main() → dynamic {
+  self::C<core::int> x = new self::C::named<core::int>(<core::int>[42]);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.direct.transformed.expect
new file mode 100644
index 0000000..d2fa30a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class C<T extends core::Object> extends core::Object {
+  static field dynamic _redirecting# = <dynamic>[self::C::•];
+  abstract get t() → self::C::T;
+  abstract set t(self::C::T x) → void;
+  static factory •<T extends core::Object>(self::C::•::T t) → self::C<self::C::•::T>
+    let dynamic #redirecting_factory = self::CImpl::• in let self::C::•::T #typeArg0 = null in invalid-expression;
+}
+class CImpl<T extends core::Object> extends core::Object implements self::C<self::CImpl::T> {
+  field self::CImpl::T t;
+  constructor •(self::CImpl::T t) → void
+    : self::CImpl::t = t, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic x = new self::CImpl::•<dynamic>(42);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.transformed.expect
new file mode 100644
index 0000000..b46bcd1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class C<T extends core::Object> extends core::Object {
+  static field dynamic _redirecting# = <dynamic>[self::C::•];
+  abstract get t() → self::C::T;
+  abstract set t(generic-covariant-impl generic-covariant-interface self::C::T x) → void;
+  static factory •<T extends core::Object>(self::C::•::T t) → self::C<self::C::•::T>
+    let<BottomType> #redirecting_factory = self::CImpl::• in let self::C::•::T #typeArg0 = null in invalid-expression;
+}
+class CImpl<T extends core::Object> extends core::Object implements self::C<self::CImpl::T> {
+  generic-covariant-impl generic-covariant-interface field self::CImpl::T t;
+  constructor •(self::CImpl::T t) → void
+    : self::CImpl::t = t, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::C<core::int> x = new self::CImpl::•<core::int>(42);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.direct.transformed.expect
new file mode 100644
index 0000000..1975274
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class C<T extends core::Object> extends core::Object {
+  static field dynamic _redirecting# = <dynamic>[self::C::•];
+  abstract get t() → self::C::T;
+  abstract set t(self::C::T x) → void;
+  static factory •<T extends core::Object>(self::C::•::T t) → self::C<self::C::•::T>
+    let dynamic #redirecting_factory = self::CImpl::• in let self::C::•::T #typeArg0 = null in invalid-expression;
+}
+class CImpl<T extends core::Object> extends core::Object implements self::C<self::CImpl::T> {
+  field self::CImpl::T t;
+  constructor _(self::CImpl::T t) → void
+    : self::CImpl::t = t, super core::Object::•()
+    ;
+  static factory •<T extends core::Object>(self::CImpl::•::T t) → self::CImpl<self::CImpl::•::T>
+    return new self::CImpl::_<dynamic>(t);
+}
+static method main() → dynamic {
+  dynamic x = self::CImpl::•<dynamic>(42);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect
new file mode 100644
index 0000000..e599360
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class C<T extends core::Object> extends core::Object {
+  static field dynamic _redirecting# = <dynamic>[self::C::•];
+  abstract get t() → self::C::T;
+  abstract set t(generic-covariant-impl generic-covariant-interface self::C::T x) → void;
+  static factory •<T extends core::Object>(self::C::•::T t) → self::C<self::C::•::T>
+    let <T extends core::Object>(self::CImpl::•::T) → self::CImpl<self::CImpl::•::T> #redirecting_factory = self::CImpl::• in let self::C::•::T #typeArg0 = null in invalid-expression;
+}
+class CImpl<T extends core::Object> extends core::Object implements self::C<self::CImpl::T> {
+  generic-covariant-impl generic-covariant-interface field self::CImpl::T t;
+  constructor _(self::CImpl::T t) → void
+    : self::CImpl::t = t, super core::Object::•()
+    ;
+  static factory •<T extends core::Object>(self::CImpl::•::T t) → self::CImpl<self::CImpl::•::T>
+    return new self::CImpl::_<self::CImpl::•::T>(t);
+}
+static method main() → dynamic {
+  self::C<core::int> x = self::CImpl::•<core::int>(42);
+}
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.direct.transformed.expect
new file mode 100644
index 0000000..25d5c94
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Clonable<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Pair<T extends self::Clonable<self::Pair::T>, U extends self::Clonable<self::Pair::U>> extends core::Object {
+  field self::Pair::T t;
+  field self::Pair::U u;
+  constructor •(self::Pair::T t, self::Pair::U u) → void
+    : self::Pair::t = t, self::Pair::u = u, super core::Object::•()
+    ;
+  constructor _() → void
+    : self::Pair::u = null, self::Pair::t = null, super core::Object::•()
+    ;
+  get reversed() → self::Pair<self::Pair::U, self::Pair::T>
+    return new self::Pair::•<dynamic, dynamic>(this.{self::Pair::u}, this.{self::Pair::t});
+}
+static method main() → dynamic {
+  final dynamic x = new self::Pair::_<dynamic, dynamic>();
+}
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
new file mode 100644
index 0000000..6b36422
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Clonable<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Pair<T extends self::Clonable<self::Pair::T>, U extends self::Clonable<self::Pair::U>> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::Pair::T t;
+  generic-covariant-impl generic-covariant-interface field self::Pair::U u;
+  constructor •(self::Pair::T t, self::Pair::U u) → void
+    : self::Pair::t = t, self::Pair::u = u, super core::Object::•()
+    ;
+  constructor _() → void
+    : self::Pair::u = null, self::Pair::t = null, super core::Object::•()
+    ;
+  get reversed() → self::Pair<self::Pair::U, self::Pair::T>
+    return new self::Pair::•<self::Pair::U, self::Pair::T>(this.{self::Pair::u}, this.{self::Pair::t});
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart:22:110: Error: Can't use a super-bounded type for instance creation. Got 'test::Pair<test::Clonable<dynamic>, test::Clonable<dynamic>>'.
+      new /*error:COULD_NOT_INFER,error:COULD_NOT_INFER*/ /*@typeArgs=Clonable<dynamic>, Clonable<dynamic>*/ Pair
+                                                                                                             ^"]/* from null */;
+static method main() → dynamic {
+  final self::Pair<self::Clonable<dynamic>, self::Clonable<dynamic>> x = new self::Pair::_<self::Clonable<dynamic>, self::Clonable<dynamic>>();
+}
diff --git a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.direct.transformed.expect
new file mode 100644
index 0000000..dcf34f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Pair<T extends core::Object, U extends core::Object> extends core::Object {
+  field self::Pair::T t;
+  field self::Pair::U u;
+  constructor •(self::Pair::T t, self::Pair::U u) → void
+    : self::Pair::t = t, self::Pair::u = u, super core::Object::•()
+    ;
+  get reversed() → self::Pair<self::Pair::U, self::Pair::T>
+    return new self::Pair::•<dynamic, dynamic>(this.{self::Pair::u}, this.{self::Pair::t});
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.transformed.expect
new file mode 100644
index 0000000..7db8910
--- /dev/null
+++ b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Pair<T extends core::Object, U extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::Pair::T t;
+  generic-covariant-impl generic-covariant-interface field self::Pair::U u;
+  constructor •(self::Pair::T t, self::Pair::U u) → void
+    : self::Pair::t = t, self::Pair::u = u, super core::Object::•()
+    ;
+  get reversed() → self::Pair<self::Pair::U, self::Pair::T>
+    return new self::Pair::•<self::Pair::U, self::Pair::T>(this.{self::Pair::u}, this.{self::Pair::t});
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.direct.transformed.expect
new file mode 100644
index 0000000..015c282
--- /dev/null
+++ b/pkg/front_end/testcases/inference/do_not_infer_overridden_fields_that_explicitly_say_dynamic_infer.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → dynamic
+    return 3;
+}
+static method foo() → dynamic {
+  core::String y = new self::B::•().x;
+  core::int z = new self::B::•().x;
+}
+static method main() → dynamic {
+  self::foo();
+}
diff --git a/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.direct.transformed.expect
new file mode 100644
index 0000000..e5d7297
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field dynamic x = null;
+  static field dynamic y = 3;
+  field dynamic x2 = null;
+  field dynamic y2 = 3;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic x = null;
+static field dynamic y = 3;
+static method main() → dynamic {
+  self::x;
+  self::y;
+}
diff --git a/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.strong.transformed.expect
new file mode 100644
index 0000000..6bdbf8c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_field_type_when_initializer_is_null.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field dynamic x = null;
+  static field core::int y = 3;
+  field dynamic x2 = null;
+  field core::int y2 = 3;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic x = null;
+static field core::int y = 3;
+static method main() → dynamic {
+  self::x;
+  self::y;
+}
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.direct.transformed.expect
new file mode 100644
index 0000000..6fc489d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+
+static method test() → dynamic {
+  dynamic x = 3;
+  x = "hi";
+}
+static method main() → dynamic {
+  self::test();
+}
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.strong.transformed.expect
new file mode 100644
index 0000000..6fc489d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_on_dynamic.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+
+static method test() → dynamic {
+  dynamic x = 3;
+  x = "hi";
+}
+static method main() → dynamic {
+  self::test();
+}
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.direct.transformed.expect
new file mode 100644
index 0000000..7dd89fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+
+static method test() → dynamic {
+  dynamic x = null;
+  x = "hi";
+  x = 3;
+}
+static method main() → dynamic {
+  self::test();
+}
diff --git a/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.strong.transformed.expect
new file mode 100644
index 0000000..7dd89fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dont_infer_type_when_initializer_is_null.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+
+static method test() → dynamic {
+  dynamic x = null;
+  x = "hi";
+  x = 3;
+}
+static method main() → dynamic {
+  self::test();
+}
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.direct.transformed.expect
new file mode 100644
index 0000000..c510acf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+
+static method f() → dynamic {
+  core::num x;
+  dynamic y;
+  core::num a = math::max<dynamic>(x, y);
+  core::Object b = math::max<dynamic>(x, y);
+  dynamic c = math::max<dynamic>(x, y);
+  dynamic d = math::max<dynamic>(x, y);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.transformed.expect
new file mode 100644
index 0000000..43da4369
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_fixes_no_upwards_errors.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+
+static method f() → dynamic {
+  core::num x;
+  dynamic y;
+  core::num a = math::max<core::num>(x, y as{TypeError} core::num);
+  core::Object b = math::max<core::num>(x, y as{TypeError} core::num);
+  dynamic c = math::max<dynamic>(x, y);
+  dynamic d = math::max<dynamic>(x, y);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.direct.transformed.expect
new file mode 100644
index 0000000..3fbf5b6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef Function2<S extends core::Object, T extends core::Object> = (S) → T;
+class A<T extends core::Object> extends core::Object {
+  field (self::A::T) → self::A::T x;
+  constructor •((self::A::T) → self::A::T x) → void
+    : self::A::x = x, super core::Object::•()
+    ;
+}
+static method main() → void {
+  {
+    dynamic x = "hello";
+    dynamic y = 3;
+    function f(core::List<core::Map<core::int, core::String>> l) → void {}
+    ;
+    f.call(<dynamic>[<dynamic, dynamic>{y: x}]);
+  }
+  {
+    function f(core::int x) → core::int
+      return 0;
+    self::A<core::int> a = new self::A::•<dynamic>(f);
+  }
+}
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect
new file mode 100644
index 0000000..33bcd2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef Function2<S extends core::Object, T extends core::Object> = (S) → T;
+class A<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface generic-contravariant field (self::A::T) → self::A::T x;
+  constructor •((self::A::T) → self::A::T x) → void
+    : self::A::x = x, super core::Object::•()
+    ;
+}
+static method main() → void {
+  {
+    core::String x = "hello";
+    core::int y = 3;
+    function f(core::List<core::Map<core::int, core::String>> l) → void {}
+    ;
+    f.call(<core::Map<core::int, core::String>>[<core::int, core::String>{y: x}]);
+  }
+  {
+    function f(core::int x) → core::int
+      return 0;
+    self::A<core::int> a = new self::A::•<core::int>(f);
+  }
+}
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..95f7601
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get foo() → core::Iterable<core::String>;
+}
+class B extends core::Object implements self::A {
+  final field dynamic foo = const <dynamic>[];
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..f7a8373
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_context_from_inferred_field_type.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get foo() → core::Iterable<core::String>;
+}
+class B extends core::Object implements self::A {
+  final field core::Iterable<core::String> foo = const <core::String>[];
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.direct.transformed.expect
new file mode 100644
index 0000000..38617da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+  const constructor named(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+@self::Foo::•(const <dynamic>[])
+class Bar extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+@self::Foo::named(const <dynamic>[])
+class Baz extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.strong.transformed.expect
new file mode 100644
index 0000000..010338c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+  const constructor named(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+@self::Foo::•(const <core::String>[])
+class Bar extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+@self::Foo::named(const <core::String>[])
+class Baz extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.direct.transformed.expect
new file mode 100644
index 0000000..56934bc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+abstract class Bar extends core::Object {
+  @self::Foo::•(const <dynamic>[])
+  field dynamic x = null;
+  @self::Foo::•(const <dynamic>[])
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  @self::Foo::•(const <dynamic>[])
+  abstract method f() → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.strong.transformed.expect
new file mode 100644
index 0000000..32a28d4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_class_members.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+abstract class Bar extends core::Object {
+  @self::Foo::•(const <core::String>[])
+  field dynamic x = null;
+  @self::Foo::•(const <core::String>[])
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  @self::Foo::•(const <core::String>[])
+  abstract method f() → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.transformed.expect
new file mode 100644
index 0000000..84e4744
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  for (core::int i = 0; i.<(1); i = i.+(1)) {
+  }
+  for (core::int i in <dynamic>[0]) {
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.transformed.expect
new file mode 100644
index 0000000..d3afdb6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(dynamic l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  const dynamic x = 0;
+  dynamic y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.transformed.expect
new file mode 100644
index 0000000..306b574
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m(dynamic x) → void {}
+}
+static method f(dynamic x) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.transformed.expect
new file mode 100644
index 0000000..d53d84c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  function f(dynamic x) → void {}
+  dynamic x = (dynamic x) → dynamic {};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.direct.transformed.expect
new file mode 100644
index 0000000..c798f57
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = () → void;
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>() → void {}
+}
+static method f<T extends core::Object>() → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.transformed.expect
new file mode 100644
index 0000000..4d24a73
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  function f<T extends core::Object>() → void {}
+  dynamic x = <T extends core::Object>() → dynamic {};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.direct.transformed.expect
new file mode 100644
index 0000000..b644cd1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+@self::Foo::•(const <dynamic>[])
+typedef F = () → void;
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.strong.transformed.expect
new file mode 100644
index 0000000..848f2f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_typedef.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+@self::Foo::•(const <core::String>[])
+typedef F = () → void;
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.direct.transformed.expect
new file mode 100644
index 0000000..e801592
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::List<core::int> l;
+  l = <dynamic>["hello"];
+  l = l = <dynamic>[1];
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect
new file mode 100644
index 0000000..f630d02
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::List<core::int> l;
+  l = <core::int>[let final core::String #t1 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_assignment_statements.dart:10:69: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  l = /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"];
+                                                                    ^"];
+  l = l = <core::int>[1];
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.direct.transformed.expect
new file mode 100644
index 0000000..126c90b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.direct.transformed.expect
@@ -0,0 +1,36 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → asy::Future<dynamic> /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        dynamic d;
+        [yield] let dynamic #t1 = asy::_awaitHelper(<dynamic>[d], :async_op_then, :async_op_error, :async_op) in null;
+        core::List<core::int> l0 = :result;
+        [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<dynamic>(<dynamic>[d]), :async_op_then, :async_op_error, :async_op) in null;
+        core::List<core::int> l1 = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
new file mode 100644
index 0000000..c7716b6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → asy::Future<dynamic> /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        dynamic d;
+        [yield] let dynamic #t1 = asy::_awaitHelper(<core::int>[d as{TypeError} core::int], :async_op_then, :async_op_error, :async_op) in null;
+        core::List<core::int> l0 = :result;
+        [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::List<core::int>>(<core::int>[d as{TypeError} core::int]), :async_op_then, :async_op_error, :async_op) in null;
+        core::List<core::int> l1 = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.direct.transformed.expect
new file mode 100644
index 0000000..ef5dc3a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.direct.transformed.expect
@@ -0,0 +1,226 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+abstract class MyStream<T extends core::Object> extends asy::Stream<self::MyStream::T> {
+  static factory •<T extends core::Object>() → self::MyStream<self::MyStream::•::T>
+    return null;
+}
+static method F<T extends core::Object>() → self::F::T
+  return null;
+static method f() → asy::Future<dynamic> /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        dynamic d;
+        core::Object o;
+        for (dynamic x in self::F<dynamic>()) {
+        }
+        for (dynamic x in self::F<dynamic>()) {
+        }
+        for (core::Object x in self::F<dynamic>()) {
+        }
+        for (final dynamic #t1 in self::F<dynamic>()) {
+          d = #t1;
+        }
+        for (final dynamic #t2 in self::F<dynamic>()) {
+          o = #t2;
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(self::F<dynamic>());
+          try
+            #L2:
+            while (true) {
+              [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L2;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(self::F<dynamic>());
+          try
+            #L3:
+            while (true) {
+              [yield] let dynamic #t5 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L3;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<core::Object> :for-iterator = new asy::_StreamIterator::•<core::Object>(self::F<dynamic>());
+          try
+            #L4:
+            while (true) {
+              [yield] let dynamic #t7 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                core::Object x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L4;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t8 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(self::F<dynamic>());
+          try
+            #L5:
+            while (true) {
+              [yield] let dynamic #t9 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t10 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  d = #t10;
+                }
+              }
+              else
+                break #L5;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t11 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(self::F<dynamic>());
+          try
+            #L6:
+            while (true) {
+              [yield] let dynamic #t12 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t13 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  o = #t13;
+                }
+              }
+              else
+                break #L6;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t14 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → asy::Future<dynamic> /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L7:
+      {
+        for (core::int x in <dynamic>[1, 2, 3]) {
+        }
+        for (core::num x in <dynamic>[1, 2, 3]) {
+        }
+        for (dynamic x in <dynamic>[1, 2, 3]) {
+        }
+        {
+          asy::_StreamIterator<core::int> :for-iterator = new asy::_StreamIterator::•<core::int>(self::MyStream::•<dynamic>());
+          try
+            #L8:
+            while (true) {
+              [yield] let dynamic #t15 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                core::int x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L8;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t16 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(self::MyStream::•<core::int>());
+          try
+            #L9:
+            while (true) {
+              [yield] let dynamic #t17 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L9;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t18 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
new file mode 100644
index 0000000..2138cb0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
@@ -0,0 +1,226 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+abstract class MyStream<T extends core::Object> extends asy::Stream<self::MyStream::T> {
+  static factory •<T extends core::Object>() → self::MyStream<self::MyStream::•::T>
+    return null;
+}
+static method F<T extends core::Object>() → self::F::T
+  return null;
+static method f() → asy::Future<dynamic> /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        dynamic d;
+        core::Object o;
+        for (dynamic x in self::F<core::Iterable<dynamic>>()) {
+        }
+        for (dynamic x in self::F<core::Iterable<dynamic>>()) {
+        }
+        for (core::Object x in self::F<core::Iterable<core::Object>>()) {
+        }
+        for (final dynamic #t1 in self::F<core::Iterable<dynamic>>()) {
+          d = #t1;
+        }
+        for (final core::Object #t2 in self::F<core::Iterable<core::Object>>()) {
+          o = #t2;
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(self::F<asy::Stream<dynamic>>());
+          try
+            #L2:
+            while (true) {
+              [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L2;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(self::F<asy::Stream<dynamic>>());
+          try
+            #L3:
+            while (true) {
+              [yield] let dynamic #t5 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L3;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<core::Object> :for-iterator = new asy::_StreamIterator::•<core::Object>(self::F<asy::Stream<core::Object>>());
+          try
+            #L4:
+            while (true) {
+              [yield] let dynamic #t7 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                core::Object x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L4;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t8 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(self::F<asy::Stream<dynamic>>());
+          try
+            #L5:
+            while (true) {
+              [yield] let dynamic #t9 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t10 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  d = #t10;
+                }
+              }
+              else
+                break #L5;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t11 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<core::Object> :for-iterator = new asy::_StreamIterator::•<core::Object>(self::F<asy::Stream<core::Object>>());
+          try
+            #L6:
+            while (true) {
+              [yield] let dynamic #t12 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final core::Object #t13 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  o = #t13;
+                }
+              }
+              else
+                break #L6;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t14 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → asy::Future<dynamic> /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L7:
+      {
+        for (core::int x in <core::int>[1, 2, 3]) {
+        }
+        for (core::num x in <core::num>[1, 2, 3]) {
+        }
+        for (core::int x in <core::int>[1, 2, 3]) {
+        }
+        {
+          asy::_StreamIterator<core::int> :for-iterator = new asy::_StreamIterator::•<core::int>(self::MyStream::•<core::int>());
+          try
+            #L8:
+            while (true) {
+              [yield] let dynamic #t15 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                core::int x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L8;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t16 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<core::int> :for-iterator = new asy::_StreamIterator::•<core::int>(self::MyStream::•<core::int>());
+          try
+            #L9:
+            while (true) {
+              [yield] let dynamic #t17 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                core::int x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L9;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t18 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.direct.transformed.expect
new file mode 100644
index 0000000..cb0d81e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef Function2<S extends core::Object, T extends core::Object> = ([S]) → T;
+class Foo extends core::Object {
+  field core::List<core::int> x;
+  constructor •([core::List<core::int> x = const <dynamic>[1]]) → void
+    : self::Foo::x = x, super core::Object::•()
+    ;
+  constructor named([core::List<core::int> x = const <dynamic>[1]]) → void
+    : self::Foo::x = null, super core::Object::•()
+    ;
+}
+static field ([core::List<core::int>]) → core::String g = ([dynamic llll = const <dynamic>[1]]) → dynamic => "hello";
+static method f([core::List<core::int> l = const <dynamic>[1]]) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.transformed.expect
new file mode 100644
index 0000000..29996bd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_initializing_formal_default_formal.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef Function2<S extends core::Object, T extends core::Object> = ([S]) → T;
+class Foo extends core::Object {
+  field core::List<core::int> x;
+  constructor •([core::List<core::int> x = const <core::int>[1]]) → void
+    : self::Foo::x = x, super core::Object::•()
+    ;
+  constructor named([core::List<core::int> x = const <core::int>[1]]) → void
+    : self::Foo::x = null, super core::Object::•()
+    ;
+}
+static field ([core::List<core::int>]) → core::String g = ([core::List<core::int> llll = const <core::int>[1]]) → core::String => "hello";
+static method f([core::List<core::int> l = const <core::int>[1]]) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.direct.transformed.expect
new file mode 100644
index 0000000..ca9246e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field self::B<core::int> b = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  constructor •(self::B::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic t1 = let final dynamic #t1 = new self::A::•() in let final dynamic #t2 = #t1.b = new self::B::•<dynamic>(1) in #t1;
+static field dynamic t2 = <self::B<core::int>>[new self::B::•<dynamic>(2)];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.transformed.expect
new file mode 100644
index 0000000..e377e03
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field self::B<core::int> b = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  constructor •(self::B::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field self::A t1 = let final self::A #t1 = new self::A::•() in let final self::B<core::int> #t2 = #t1.{self::A::b} = new self::B::•<core::int>(1) in #t1;
+static field core::List<self::B<core::int>> t2 = <self::B<core::int>>[new self::B::•<core::int>(2)];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..da516ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  constructor •(self::A::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic t1 = <self::A<core::int>>[new self::A::•<dynamic>(1)];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..d0e29da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_inside_top_level_2.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  constructor •(self::A::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<self::A<core::int>> t1 = <self::A<core::int>>[new self::A::•<core::int>(1)];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..58dbf9c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.direct.transformed.expect
@@ -0,0 +1,47 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class F0 extends core::Object {
+  constructor •(core::List<core::int> a) → void
+    : super core::Object::•() {}
+}
+class F1 extends core::Object {
+  constructor •({core::List<core::int> a = null}) → void
+    : super core::Object::•() {}
+}
+class F2 extends core::Object {
+  constructor •(core::Iterable<core::int> a) → void
+    : super core::Object::•() {}
+}
+class F3 extends core::Object {
+  constructor •(core::Iterable<core::Iterable<core::int>> a) → void
+    : super core::Object::•() {}
+}
+class F4 extends core::Object {
+  constructor •({core::Iterable<core::Iterable<core::int>> a = null}) → void
+    : super core::Object::•() {}
+}
+static method test() → void {
+  new self::F0::•(<dynamic>[]);
+  new self::F0::•(<dynamic>[3]);
+  new self::F0::•(<dynamic>["hello"]);
+  new self::F0::•(<dynamic>["hello", 3]);
+  new self::F1::•(a: <dynamic>[]);
+  new self::F1::•(a: <dynamic>[3]);
+  new self::F1::•(a: <dynamic>["hello"]);
+  new self::F1::•(a: <dynamic>["hello", 3]);
+  new self::F2::•(<dynamic>[]);
+  new self::F2::•(<dynamic>[3]);
+  new self::F2::•(<dynamic>["hello"]);
+  new self::F2::•(<dynamic>["hello", 3]);
+  new self::F3::•(<dynamic>[]);
+  new self::F3::•(<dynamic>[<dynamic>[3]]);
+  new self::F3::•(<dynamic>[<dynamic>["hello"]]);
+  new self::F3::•(<dynamic>[<dynamic>["hello"], <dynamic>[3]]);
+  new self::F4::•(a: <dynamic>[]);
+  new self::F4::•(a: <dynamic>[<dynamic>[3]]);
+  new self::F4::•(a: <dynamic>[<dynamic>["hello"]]);
+  new self::F4::•(a: <dynamic>[<dynamic>["hello"], <dynamic>[3]]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..e235fe9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart.strong.transformed.expect
@@ -0,0 +1,77 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class F0 extends core::Object {
+  constructor •(core::List<core::int> a) → void
+    : super core::Object::•() {}
+}
+class F1 extends core::Object {
+  constructor •({core::List<core::int> a = null}) → void
+    : super core::Object::•() {}
+}
+class F2 extends core::Object {
+  constructor •(core::Iterable<core::int> a) → void
+    : super core::Object::•() {}
+}
+class F3 extends core::Object {
+  constructor •(core::Iterable<core::Iterable<core::int>> a) → void
+    : super core::Object::•() {}
+}
+class F4 extends core::Object {
+  constructor •({core::Iterable<core::Iterable<core::int>> a = null}) → void
+    : super core::Object::•() {}
+}
+static method test() → void {
+  new self::F0::•(<core::int>[]);
+  new self::F0::•(<core::int>[3]);
+  new self::F0::•(<core::int>[let final core::String #t1 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:32:69: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
+                                                                    ^"]);
+  new self::F0::•(<core::int>[let final core::String #t2 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                               ^", 3]);
+  new self::F1::•(a: <core::int>[]);
+  new self::F1::•(a: <core::int>[3]);
+  new self::F1::•(a: <core::int>[let final core::String #t3 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
+                                               ^"]);
+  new self::F1::•(a: <core::int>[let final core::String #t4 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                               ^", 3]);
+  new self::F2::•(<core::int>[]);
+  new self::F2::•(<core::int>[3]);
+  new self::F2::•(<core::int>[let final core::String #t5 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:51:69: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
+                                                                    ^"]);
+  new self::F2::•(<core::int>[let final core::String #t6 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                               ^", 3]);
+  new self::F3::•(<core::Iterable<core::int>>[]);
+  new self::F3::•(<core::Iterable<core::int>>[<core::int>[3]]);
+  new self::F3::•(<core::Iterable<core::int>>[<core::int>[let final core::String #t7 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:62:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
+                                                                  ^"]]);
+  new self::F3::•(<core::Iterable<core::int>>[<core::int>[let final core::String #t8 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:65:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
+                                                                  ^"], <core::int>[3]]);
+  new self::F4::•(a: <core::Iterable<core::int>>[]);
+  new self::F4::•(a: <core::Iterable<core::int>>[<core::int>[3]]);
+  new self::F4::•(a: <core::Iterable<core::int>>[<core::int>[let final core::String #t9 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:74:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
+                                                                  ^"]]);
+  new self::F4::•(a: <core::Iterable<core::int>>[<core::int>[let final core::String #t10 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_constructor_arguments_infer_downwards.dart:77:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
+                                                                  ^"], <core::int>[3]]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..c1a3c1f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.direct.transformed.expect
@@ -0,0 +1,32 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f0(core::List<core::int> a) → void {}
+static method f1({core::List<core::int> a = null}) → void {}
+static method f2(core::Iterable<core::int> a) → void {}
+static method f3(core::Iterable<core::Iterable<core::int>> a) → void {}
+static method f4({core::Iterable<core::Iterable<core::int>> a = null}) → void {}
+static method test() → void {
+  self::f0(<dynamic>[]);
+  self::f0(<dynamic>[3]);
+  self::f0(<dynamic>["hello"]);
+  self::f0(<dynamic>["hello", 3]);
+  self::f1(a: <dynamic>[]);
+  self::f1(a: <dynamic>[3]);
+  self::f1(a: <dynamic>["hello"]);
+  self::f1(a: <dynamic>["hello", 3]);
+  self::f2(<dynamic>[]);
+  self::f2(<dynamic>[3]);
+  self::f2(<dynamic>["hello"]);
+  self::f2(<dynamic>["hello", 3]);
+  self::f3(<dynamic>[]);
+  self::f3(<dynamic>[<dynamic>[3]]);
+  self::f3(<dynamic>[<dynamic>["hello"]]);
+  self::f3(<dynamic>[<dynamic>["hello"], <dynamic>[3]]);
+  self::f4(a: <dynamic>[]);
+  self::f4(a: <dynamic>[<dynamic>[3]]);
+  self::f4(a: <dynamic>[<dynamic>["hello"]]);
+  self::f4(a: <dynamic>[<dynamic>["hello"], <dynamic>[3]]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..9e5a69c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f0(core::List<core::int> a) → void {}
+static method f1({core::List<core::int> a = null}) → void {}
+static method f2(core::Iterable<core::int> a) → void {}
+static method f3(core::Iterable<core::Iterable<core::int>> a) → void {}
+static method f4({core::Iterable<core::Iterable<core::int>> a = null}) → void {}
+static method test() → void {
+  self::f0(<core::int>[]);
+  self::f0(<core::int>[3]);
+  self::f0(<core::int>[let final core::String #t1 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:16:68: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  f0(/*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
+                                                                   ^"]);
+  self::f0(<core::int>[let final core::String #t2 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:17:68: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  f0(/*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\", 3]);
+                                                                   ^", 3]);
+  self::f1(a: <core::int>[]);
+  self::f1(a: <core::int>[3]);
+  self::f1(a: <core::int>[let final core::String #t3 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:21:71: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  f1(a: /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
+                                                                      ^"]);
+  self::f1(a: <core::int>[let final core::String #t4 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:23:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                               ^", 3]);
+  self::f2(<core::int>[]);
+  self::f2(<core::int>[3]);
+  self::f2(<core::int>[let final core::String #t5 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:29:68: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  f2(/*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
+                                                                   ^"]);
+  self::f2(<core::int>[let final core::String #t6 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:30:68: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  f2(/*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\", 3]);
+                                                                   ^", 3]);
+  self::f3(<core::Iterable<core::int>>[]);
+  self::f3(<core::Iterable<core::int>>[<core::int>[3]]);
+  self::f3(<core::Iterable<core::int>>[<core::int>[let final core::String #t7 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:37:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
+                                                                  ^"]]);
+  self::f3(<core::Iterable<core::int>>[<core::int>[let final core::String #t8 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:40:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
+                                                                  ^"], <core::int>[3]]);
+  self::f4(a: <core::Iterable<core::int>>[]);
+  self::f4(a: <core::Iterable<core::int>>[<core::int>[3]]);
+  self::f4(a: <core::Iterable<core::int>>[<core::int>[let final core::String #t9 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:49:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
+                                                                  ^"]]);
+  self::f4(a: <core::Iterable<core::int>>[<core::int>[let final core::String #t10 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_arguments_infer_downwards.dart:52:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
+                                                                  ^"], <core::int>[3]]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.direct.transformed.expect
new file mode 100644
index 0000000..12eb980
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.direct.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef Function2<S extends core::Object, T extends core::Object> = (S) → T;
+static method test() → void {
+  {
+    (core::int) → core::String l0 = (core::int x) → dynamic => null;
+    (core::int) → core::String l1 = (core::int x) → dynamic => "hello";
+    (core::int) → core::String l2 = (core::String x) → dynamic => "hello";
+    (core::int) → core::String l3 = (core::int x) → dynamic => 3;
+    (core::int) → core::String l4 = (core::int x) → dynamic {
+      return 3;
+    };
+  }
+  {
+    (core::int) → core::String l0 = (dynamic x) → dynamic => null;
+    (core::int) → core::String l1 = (dynamic x) → dynamic => "hello";
+    (core::int) → core::String l2 = (dynamic x) → dynamic => 3;
+    (core::int) → core::String l3 = (dynamic x) → dynamic {
+      return 3;
+    };
+    (core::int) → core::String l4 = (dynamic x) → dynamic {
+      return x;
+    };
+  }
+  {
+    (core::int) → core::List<core::String> l0 = (core::int x) → dynamic => null;
+    (core::int) → core::List<core::String> l1 = (core::int x) → dynamic => <dynamic>["hello"];
+    (core::int) → core::List<core::String> l2 = (core::String x) → dynamic => <dynamic>["hello"];
+    (core::int) → core::List<core::String> l3 = (core::int x) → dynamic => <dynamic>[3];
+    (core::int) → core::List<core::String> l4 = (core::int x) → dynamic {
+      return <dynamic>[3];
+    };
+  }
+  {
+    (core::int) → core::int l0 = (dynamic x) → dynamic => x;
+    (core::int) → core::int l1 = (dynamic x) → dynamic => x.+(1);
+    (core::int) → core::String l2 = (dynamic x) → dynamic => x;
+    (core::int) → core::String l3 = (dynamic x) → dynamic => x.substring(3);
+    (core::String) → core::String l4 = (dynamic x) → dynamic => x.substring(3);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
new file mode 100644
index 0000000..d8951be
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart.strong.transformed.expect
@@ -0,0 +1,77 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef Function2<S extends core::Object, T extends core::Object> = (S) → T;
+static method test() → void {
+  {
+    (core::int) → core::String l0 = (core::int x) → core::Null => null;
+    (core::int) → core::String l1 = (core::int x) → core::String => "hello";
+    (core::int) → core::String l2 = let final (core::String) → core::String #t1 = (core::String x) → core::String => "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:15:66: Error: A value of type '(dart.core::String) \u8594 dart.core::String' can't be assigned to a variable of type '(dart.core::int) \u8594 dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.core::int) \u8594 dart.core::String'.
+        l2 = /*error:INVALID_ASSIGNMENT*/ /*@returnType=String*/ (String x) =>
+                                                                 ^";
+    (core::int) → core::String l3 = (core::int x) → core::String => let final core::int #t2 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:18:77: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        l3 = /*error:INVALID_ASSIGNMENT*/ /*@returnType=String*/ (int x) => 3;
+                                                                            ^";
+    (core::int) → core::String l4 = (core::int x) → core::String {
+      return let final core::int #t3 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:20:47: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      return /*error:RETURN_OF_INVALID_TYPE*/ 3;
+                                              ^";
+    };
+  }
+  {
+    (core::int) → core::String l0 = (core::int x) → core::Null => null;
+    (core::int) → core::String l1 = (core::int x) → core::String => "hello";
+    (core::int) → core::String l2 = (core::int x) → core::String => let final core::int #t4 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:29:13: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+            3;
+            ^";
+    (core::int) → core::String l3 = (core::int x) → core::String {
+      return let final core::int #t5 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:31:47: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      return /*error:RETURN_OF_INVALID_TYPE*/ 3;
+                                              ^";
+    };
+    (core::int) → core::String l4 = (core::int x) → core::String {
+      return let final core::int #t6 = x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:34:47: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      return /*error:RETURN_OF_INVALID_TYPE*/ x;
+                                              ^";
+    };
+  }
+  {
+    (core::int) → core::List<core::String> l0 = (core::int x) → core::Null => null;
+    (core::int) → core::List<core::String> l1 = (core::int x) → core::List<core::String> => <core::String>["hello"];
+    (core::int) → core::List<core::String> l2 = let final (core::String) → core::List<core::String> #t7 = (core::String x) → core::List<core::String> => <core::String>["hello"] in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:42:72: Error: A value of type '(dart.core::String) \u8594 dart.core::List<dart.core::String>' can't be assigned to a variable of type '(dart.core::int) \u8594 dart.core::List<dart.core::String>'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.core::int) \u8594 dart.core::List<dart.core::String>'.
+        l2 = /*error:INVALID_ASSIGNMENT*/ /*@returnType=List<String>*/ (String
+                                                                       ^";
+    (core::int) → core::List<core::String> l3 = (core::int x) → core::List<core::String> => <core::String>[let final core::int #t8 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:46:58: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+              /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
+                                                         ^"];
+    (core::int) → core::List<core::String> l4 = (core::int x) → core::List<core::String> {
+      return <core::String>[let final core::int #t9 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:50:52: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
+                                                   ^"];
+    };
+  }
+  {
+    (core::int) → core::int l0 = (core::int x) → core::int => x;
+    (core::int) → core::int l1 = (core::int x) → core::int => x.{core::num::+}(1);
+    (core::int) → core::String l2 = (core::int x) → core::String => let final core::int #t10 = x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:60:13: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+            x;
+            ^";
+    (core::int) → core::String l3 = (core::int x) → core::String => (let final core::int #t11 = x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_function_expressions.dart:63:14: Error: The method 'substring' isn't defined for the class 'dart.core::int'.
+Try correcting the name to the name of an existing method, or defining a method named 'substring'.
+            .substring(3);
+             ^") as{TypeError} core::String;
+    (core::String) → core::String l4 = (core::String x) → core::String => x.{core::String::substring}(3);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.direct.transformed.expect
new file mode 100644
index 0000000..5ffe78d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_function_of_t_using_the_t.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → void {
+  {
+    function f<T extends core::Object>(T x) → T
+      return null;
+    dynamic v1 = f;
+    v1 = <S extends core::Object>(dynamic x) → dynamic => x;
+  }
+  {
+    function f<T extends core::Object>(T x) → core::List<T>
+      return null;
+    dynamic v2 = f;
+    v2 = <S extends core::Object>(dynamic x) → dynamic => <dynamic>[x];
+    core::Iterable<core::int> r = v2.call(42);
+    core::Iterable<core::String> s = v2.call("hello");
+    core::Iterable<core::List<core::int>> t = v2.call(<core::int>[]);
+    core::Iterable<core::num> u = v2.call(42);
+    core::Iterable<core::num> v = v2.call<core::num>(42);
+  }
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.direct.transformed.expect
new file mode 100644
index 0000000..995d542
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class F3<T extends core::Object> extends core::Object {
+  constructor •(core::Iterable<core::Iterable<self::F3::T>> a) → void
+    : super core::Object::•() {}
+}
+class F4<T extends core::Object> extends core::Object {
+  constructor •({core::Iterable<core::Iterable<self::F4::T>> a = null}) → void
+    : super core::Object::•() {}
+}
+static method main() → void {
+  new self::F3::•<dynamic>(<dynamic>[]);
+  new self::F4::•<dynamic>(a: <dynamic>[]);
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.strong.transformed.expect
new file mode 100644
index 0000000..8c1b574
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_empty_list.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class F3<T extends core::Object> extends core::Object {
+  constructor •(core::Iterable<core::Iterable<self::F3::T>> a) → void
+    : super core::Object::•() {}
+}
+class F4<T extends core::Object> extends core::Object {
+  constructor •({core::Iterable<core::Iterable<self::F4::T>> a = null}) → void
+    : super core::Object::•() {}
+}
+static method main() → void {
+  new self::F3::•<dynamic>(<core::Iterable<dynamic>>[]);
+  new self::F4::•<dynamic>(a: <core::Iterable<dynamic>>[]);
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..336e915
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.direct.transformed.expect
@@ -0,0 +1,55 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class F0<T extends core::Object> extends core::Object {
+  constructor •(core::List<self::F0::T> a) → void
+    : super core::Object::•() {}
+}
+class F1<T extends core::Object> extends core::Object {
+  constructor •({core::List<self::F1::T> a = null}) → void
+    : super core::Object::•() {}
+}
+class F2<T extends core::Object> extends core::Object {
+  constructor •(core::Iterable<self::F2::T> a) → void
+    : super core::Object::•() {}
+}
+class F3<T extends core::Object> extends core::Object {
+  constructor •(core::Iterable<core::Iterable<self::F3::T>> a) → void
+    : super core::Object::•() {}
+}
+class F4<T extends core::Object> extends core::Object {
+  constructor •({core::Iterable<core::Iterable<self::F4::T>> a = null}) → void
+    : super core::Object::•() {}
+}
+static method test() → void {
+  new self::F0::•<core::int>(<dynamic>[]);
+  new self::F0::•<core::int>(<dynamic>[3]);
+  new self::F0::•<core::int>(<dynamic>["hello"]);
+  new self::F0::•<core::int>(<dynamic>["hello", 3]);
+  new self::F1::•<core::int>(a: <dynamic>[]);
+  new self::F1::•<core::int>(a: <dynamic>[3]);
+  new self::F1::•<core::int>(a: <dynamic>["hello"]);
+  new self::F1::•<core::int>(a: <dynamic>["hello", 3]);
+  new self::F2::•<core::int>(<dynamic>[]);
+  new self::F2::•<core::int>(<dynamic>[3]);
+  new self::F2::•<core::int>(<dynamic>["hello"]);
+  new self::F2::•<core::int>(<dynamic>["hello", 3]);
+  new self::F3::•<core::int>(<dynamic>[]);
+  new self::F3::•<core::int>(<dynamic>[<dynamic>[3]]);
+  new self::F3::•<core::int>(<dynamic>[<dynamic>["hello"]]);
+  new self::F3::•<core::int>(<dynamic>[<dynamic>["hello"], <dynamic>[3]]);
+  new self::F4::•<core::int>(a: <dynamic>[]);
+  new self::F4::•<core::int>(a: <dynamic>[<dynamic>[3]]);
+  new self::F4::•<core::int>(a: <dynamic>[<dynamic>["hello"]]);
+  new self::F4::•<core::int>(a: <dynamic>[<dynamic>["hello"], <dynamic>[3]]);
+  new self::F3::•<dynamic>(<dynamic>[]);
+  dynamic f31 = new self::F3::•<dynamic>(<dynamic>[<dynamic>[3]]);
+  dynamic f32 = new self::F3::•<dynamic>(<dynamic>[<dynamic>["hello"]]);
+  dynamic f33 = new self::F3::•<dynamic>(<dynamic>[<dynamic>["hello"], <dynamic>[3]]);
+  new self::F4::•<dynamic>(a: <dynamic>[]);
+  new self::F4::•<dynamic>(a: <dynamic>[<dynamic>[3]]);
+  new self::F4::•<dynamic>(a: <dynamic>[<dynamic>["hello"]]);
+  new self::F4::•<dynamic>(a: <dynamic>[<dynamic>["hello"], <dynamic>[3]]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..6a665cc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart.strong.transformed.expect
@@ -0,0 +1,85 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class F0<T extends core::Object> extends core::Object {
+  constructor •(core::List<self::F0::T> a) → void
+    : super core::Object::•() {}
+}
+class F1<T extends core::Object> extends core::Object {
+  constructor •({core::List<self::F1::T> a = null}) → void
+    : super core::Object::•() {}
+}
+class F2<T extends core::Object> extends core::Object {
+  constructor •(core::Iterable<self::F2::T> a) → void
+    : super core::Object::•() {}
+}
+class F3<T extends core::Object> extends core::Object {
+  constructor •(core::Iterable<core::Iterable<self::F3::T>> a) → void
+    : super core::Object::•() {}
+}
+class F4<T extends core::Object> extends core::Object {
+  constructor •({core::Iterable<core::Iterable<self::F4::T>> a = null}) → void
+    : super core::Object::•() {}
+}
+static method test() → void {
+  new self::F0::•<core::int>(<core::int>[]);
+  new self::F0::•<core::int>(<core::int>[3]);
+  new self::F0::•<core::int>(<core::int>[let final core::String #t1 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:32:69: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
+                                                                    ^"]);
+  new self::F0::•<core::int>(<core::int>[let final core::String #t2 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:34:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                               ^", 3]);
+  new self::F1::•<core::int>(a: <core::int>[]);
+  new self::F1::•<core::int>(a: <core::int>[3]);
+  new self::F1::•<core::int>(a: <core::int>[let final core::String #t3 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:41:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
+                                               ^"]);
+  new self::F1::•<core::int>(a: <core::int>[let final core::String #t4 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:44:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                               ^", 3]);
+  new self::F2::•<core::int>(<core::int>[]);
+  new self::F2::•<core::int>(<core::int>[3]);
+  new self::F2::•<core::int>(<core::int>[let final core::String #t5 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:51:69: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]);
+                                                                    ^"]);
+  new self::F2::•<core::int>(<core::int>[let final core::String #t6 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:53:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                               ^", 3]);
+  new self::F3::•<core::int>(<core::Iterable<core::int>>[]);
+  new self::F3::•<core::int>(<core::Iterable<core::int>>[<core::int>[3]]);
+  new self::F3::•<core::int>(<core::Iterable<core::int>>[<core::int>[let final core::String #t7 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:62:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
+                                                                  ^"]]);
+  new self::F3::•<core::int>(<core::Iterable<core::int>>[<core::int>[let final core::String #t8 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:65:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
+                                                                  ^"], <core::int>[3]]);
+  new self::F4::•<core::int>(a: <core::Iterable<core::int>>[]);
+  new self::F4::•<core::int>(a: <core::Iterable<core::int>>[<core::int>[3]]);
+  new self::F4::•<core::int>(a: <core::Iterable<core::int>>[<core::int>[let final core::String #t9 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:74:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"]
+                                                                  ^"]]);
+  new self::F4::•<core::int>(a: <core::Iterable<core::int>>[<core::int>[let final core::String #t10 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_constructor_arguments_infer_downwards.dart:77:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    /*@typeArgs=int*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"],
+                                                                  ^"], <core::int>[3]]);
+  new self::F3::•<dynamic>(<core::Iterable<dynamic>>[]);
+  self::F3<core::int> f31 = new self::F3::•<core::int>(<core::List<core::int>>[<core::int>[3]]);
+  self::F3<core::String> f32 = new self::F3::•<core::String>(<core::List<core::String>>[<core::String>["hello"]]);
+  self::F3<core::Object> f33 = new self::F3::•<core::Object>(<core::List<core::Object>>[<core::String>["hello"], <core::int>[3]]);
+  new self::F4::•<dynamic>(a: <core::Iterable<dynamic>>[]);
+  new self::F4::•<core::int>(a: <core::List<core::int>>[<core::int>[3]]);
+  new self::F4::•<core::String>(a: <core::List<core::String>>[<core::String>["hello"]]);
+  new self::F4::•<core::Object>(a: <core::List<core::Object>>[<core::String>["hello"], <core::int>[3]]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.direct.transformed.expect
new file mode 100644
index 0000000..ae8eea6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.direct.transformed.expect
@@ -0,0 +1,61 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  {
+    function f<S extends core::Object>(core::int x) → core::String
+      return null;
+    dynamic v = f;
+    v = <T extends core::Object>(core::int x) → dynamic => null;
+    v = <T extends core::Object>(core::int x) → dynamic => "hello";
+    v = <T extends core::Object>(core::String x) → dynamic => "hello";
+    v = <T extends core::Object>(core::int x) → dynamic => 3;
+    v = <T extends core::Object>(core::int x) → dynamic {
+      return 3;
+    };
+  }
+  {
+    function f<S extends core::Object>(core::int x) → core::String
+      return null;
+    dynamic v = f;
+    v = <T extends core::Object>(dynamic x) → dynamic => null;
+    v = <T extends core::Object>(dynamic x) → dynamic => "hello";
+    v = <T extends core::Object>(dynamic x) → dynamic => 3;
+    v = <T extends core::Object>(dynamic x) → dynamic {
+      return 3;
+    };
+    v = <T extends core::Object>(dynamic x) → dynamic {
+      return x;
+    };
+  }
+  {
+    function f<S extends core::Object>(core::int x) → core::List<core::String>
+      return null;
+    dynamic v = f;
+    v = <T extends core::Object>(core::int x) → dynamic => null;
+    v = <T extends core::Object>(core::int x) → dynamic => <dynamic>["hello"];
+    v = <T extends core::Object>(core::String x) → dynamic => <dynamic>["hello"];
+    v = <T extends core::Object>(core::int x) → dynamic => <dynamic>[3];
+    v = <T extends core::Object>(core::int x) → dynamic {
+      return <dynamic>[3];
+    };
+  }
+  {
+    function int2int<S extends core::Object>(core::int x) → core::int
+      return null;
+    function int2String<T extends core::Object>(core::int x) → core::String
+      return null;
+    function string2String<T extends core::Object>(core::String x) → core::String
+      return null;
+    dynamic x = int2int;
+    x = <T extends core::Object>(dynamic x) → dynamic => x;
+    x = <T extends core::Object>(dynamic x) → dynamic => x.+(1);
+    dynamic y = int2String;
+    y = <T extends core::Object>(dynamic x) → dynamic => x;
+    y = <T extends core::Object>(dynamic x) → dynamic => x.substring(3);
+    dynamic z = string2String;
+    z = <T extends core::Object>(dynamic x) → dynamic => x.substring(3);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
new file mode 100644
index 0000000..4298e7b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart.strong.transformed.expect
@@ -0,0 +1,94 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  {
+    function f<S extends core::Object>(core::int x) → core::String
+      return null;
+    <S extends core::Object>(core::int) → core::String v = f;
+    v = <T extends core::Object>(core::int x) → core::Null => null;
+    v = <T extends core::Object>(core::int x) → core::String => "hello";
+    v = let final <T extends core::Object>(core::String) → core::String #t1 = <T extends core::Object>(core::String x) → core::String => "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:14:65: Error: A value of type '<T extends dart.core::Object>(dart.core::String) \u8594 dart.core::String' can't be assigned to a variable of type '<S extends dart.core::Object>(dart.core::int) \u8594 dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to '<S extends dart.core::Object>(dart.core::int) \u8594 dart.core::String'.
+    v = /*error:INVALID_ASSIGNMENT*/ <T> /*@returnType=String*/ (String x) =>
+                                                                ^";
+    v = <T extends core::Object>(core::int x) → core::String => let final core::int #t2 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:16:76: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+    v = /*error:INVALID_ASSIGNMENT*/ <T> /*@returnType=String*/ (int x) => 3;
+                                                                           ^";
+    v = <T extends core::Object>(core::int x) → core::String {
+      return let final core::int #t3 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:18:47: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      return /*error:RETURN_OF_INVALID_TYPE*/ 3;
+                                              ^";
+    };
+  }
+  {
+    function f<S extends core::Object>(core::int x) → core::String
+      return null;
+    <S extends core::Object>(core::int) → core::String v = f;
+    v = <T extends core::Object>(core::int x) → core::Null => null;
+    v = <T extends core::Object>(core::int x) → core::String => "hello";
+    v = <T extends core::Object>(core::int x) → core::String => let final core::int #t4 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:28:9: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        3;
+        ^";
+    v = <T extends core::Object>(core::int x) → core::String {
+      return let final core::int #t5 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:30:47: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      return /*error:RETURN_OF_INVALID_TYPE*/ 3;
+                                              ^";
+    };
+    v = <T extends core::Object>(core::int x) → core::String {
+      return let final core::int #t6 = x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:33:47: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      return /*error:RETURN_OF_INVALID_TYPE*/ x;
+                                              ^";
+    };
+  }
+  {
+    function f<S extends core::Object>(core::int x) → core::List<core::String>
+      return null;
+    <S extends core::Object>(core::int) → core::List<core::String> v = f;
+    v = <T extends core::Object>(core::int x) → core::Null => null;
+    v = <T extends core::Object>(core::int x) → core::List<core::String> => <core::String>["hello"];
+    v = let final <T extends core::Object>(core::String) → core::List<core::String> #t7 = <T extends core::Object>(core::String x) → core::List<core::String> => <core::String>["hello"] in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:43:71: Error: A value of type '<T extends dart.core::Object>(dart.core::String) \u8594 dart.core::List<dart.core::String>' can't be assigned to a variable of type '<S extends dart.core::Object>(dart.core::int) \u8594 dart.core::List<dart.core::String>'.
+Try changing the type of the left hand side, or casting the right hand side to '<S extends dart.core::Object>(dart.core::int) \u8594 dart.core::List<dart.core::String>'.
+    v = /*error:INVALID_ASSIGNMENT*/ <T> /*@returnType=List<String>*/ (String
+                                                                      ^";
+    v = <T extends core::Object>(core::int x) → core::List<core::String> => <core::String>[let final core::int #t8 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:46:54: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+          /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
+                                                     ^"];
+    v = <T extends core::Object>(core::int x) → core::List<core::String> {
+      return <core::String>[let final core::int #t9 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:50:52: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
+                                                   ^"];
+    };
+  }
+  {
+    function int2int<S extends core::Object>(core::int x) → core::int
+      return null;
+    function int2String<T extends core::Object>(core::int x) → core::String
+      return null;
+    function string2String<T extends core::Object>(core::String x) → core::String
+      return null;
+    <S extends core::Object>(core::int) → core::int x = int2int;
+    x = <T extends core::Object>(core::int x) → core::int => x;
+    x = <T extends core::Object>(core::int x) → core::int => x.{core::num::+}(1);
+    <T extends core::Object>(core::int) → core::String y = int2String;
+    y = <T extends core::Object>(core::int x) → core::String => let final core::int #t10 = x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:64:9: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        x;
+        ^";
+    y = <T extends core::Object>(core::int x) → core::String => (let final core::int #t11 = x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_generic_function_expressions.dart:66:10: Error: The method 'substring' isn't defined for the class 'dart.core::int'.
+Try correcting the name to the name of an existing method, or defining a method named 'substring'.
+        .substring(3);
+         ^") as{TypeError} core::String;
+    <T extends core::Object>(core::String) → core::String z = string2String;
+    z = <T extends core::Object>(core::String x) → core::String => x.{core::String::substring}(3);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..e0aaab1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.direct.transformed.expect
@@ -0,0 +1,113 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<S extends core::Object, T extends core::Object> extends core::Object {
+  field self::A::S x;
+  field self::A::T y;
+  constructor •(self::A::S x, self::A::T y) → void
+    : self::A::x = x, self::A::y = y, super core::Object::•()
+    ;
+  constructor named(self::A::S x, self::A::T y) → void
+    : self::A::x = x, self::A::y = y, super core::Object::•()
+    ;
+}
+class B<S extends core::Object, T extends core::Object> extends self::A<self::B::T, self::B::S> {
+  constructor •(self::B::S y, self::B::T x) → void
+    : super self::A::•(x, y)
+    ;
+  constructor named(self::B::S y, self::B::T x) → void
+    : super self::A::named(x, y)
+    ;
+}
+class C<S extends core::Object> extends self::B<self::C::S, self::C::S> {
+  constructor •(self::C::S a) → void
+    : super self::B::•(a, a)
+    ;
+  constructor named(self::C::S a) → void
+    : super self::B::named(a, a)
+    ;
+}
+class D<S extends core::Object, T extends core::Object> extends self::B<self::D::T, core::int> {
+  constructor •(self::D::T a) → void
+    : super self::B::•(a, 3)
+    ;
+  constructor named(self::D::T a) → void
+    : super self::B::named(a, 3)
+    ;
+}
+class E<S extends core::Object, T extends core::Object> extends self::A<self::C<self::E::S>, self::E::T> {
+  constructor •(self::E::T a) → void
+    : super self::A::•(null, a)
+    ;
+}
+class F<S extends core::Object, T extends core::Object> extends self::A<self::F::S, self::F::T> {
+  constructor •(self::F::S x, self::F::T y, {core::List<self::F::S> a = null, core::List<self::F::T> b = null}) → void
+    : super self::A::•(x, y)
+    ;
+  constructor named(self::F::S x, self::F::T y, [self::F::S a = null, self::F::T b = null]) → void
+    : super self::A::•(a, b)
+    ;
+}
+static method test() → void {
+  {
+    self::A<core::int, core::String> a0 = new self::A::•<dynamic, dynamic>(3, "hello");
+    self::A<core::int, core::String> a1 = new self::A::named<dynamic, dynamic>(3, "hello");
+    self::A<core::int, core::String> a2 = new self::A::•<core::int, core::String>(3, "hello");
+    self::A<core::int, core::String> a3 = new self::A::named<core::int, core::String>(3, "hello");
+    self::A<core::int, core::String> a4 = new self::A::•<core::int, dynamic>(3, "hello");
+    self::A<core::int, core::String> a5 = new self::A::named<dynamic, dynamic>(3, "hello");
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::A::•<dynamic, dynamic>("hello", 3);
+    self::A<core::int, core::String> a1 = new self::A::named<dynamic, dynamic>("hello", 3);
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::B::•<dynamic, dynamic>("hello", 3);
+    self::A<core::int, core::String> a1 = new self::B::named<dynamic, dynamic>("hello", 3);
+    self::A<core::int, core::String> a2 = new self::B::•<core::String, core::int>("hello", 3);
+    self::A<core::int, core::String> a3 = new self::B::named<core::String, core::int>("hello", 3);
+    self::A<core::int, core::String> a4 = new self::B::•<core::String, dynamic>("hello", 3);
+    self::A<core::int, core::String> a5 = new self::B::named<dynamic, dynamic>("hello", 3);
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::B::•<dynamic, dynamic>(3, "hello");
+    self::A<core::int, core::String> a1 = new self::B::named<dynamic, dynamic>(3, "hello");
+  }
+  {
+    self::A<core::int, core::int> a0 = new self::C::•<dynamic>(3);
+    self::A<core::int, core::int> a1 = new self::C::named<dynamic>(3);
+    self::A<core::int, core::int> a2 = new self::C::•<core::int>(3);
+    self::A<core::int, core::int> a3 = new self::C::named<core::int>(3);
+    self::A<core::int, core::int> a4 = new self::C::•<dynamic>(3);
+    self::A<core::int, core::int> a5 = new self::C::named<dynamic>(3);
+  }
+  {
+    self::A<core::int, core::int> a0 = new self::C::•<dynamic>("hello");
+    self::A<core::int, core::int> a1 = new self::C::named<dynamic>("hello");
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::D::•<dynamic, dynamic>("hello");
+    self::A<core::int, core::String> a1 = new self::D::named<dynamic, dynamic>("hello");
+    self::A<core::int, core::String> a2 = new self::D::•<core::int, core::String>("hello");
+    self::A<core::int, core::String> a3 = new self::D::named<core::String, core::String>("hello");
+    self::A<core::int, core::String> a4 = new self::D::•<core::num, dynamic>("hello");
+    self::A<core::int, core::String> a5 = new self::D::named<dynamic, dynamic>("hello");
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::D::•<dynamic, dynamic>(3);
+    self::A<core::int, core::String> a1 = new self::D::named<dynamic, dynamic>(3);
+  }
+  {
+    self::A<self::C<core::int>, core::String> a0 = new self::E::•<dynamic, dynamic>("hello");
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::F::•<dynamic, dynamic>(3, "hello", a: <dynamic>[3], b: <dynamic>["hello"]);
+    self::A<core::int, core::String> a1 = new self::F::•<dynamic, dynamic>(3, "hello", a: <dynamic>["hello"], b: <dynamic>[3]);
+    self::A<core::int, core::String> a2 = new self::F::named<dynamic, dynamic>(3, "hello", 3, "hello");
+    self::A<core::int, core::String> a3 = new self::F::named<dynamic, dynamic>(3, "hello");
+    self::A<core::int, core::String> a4 = new self::F::named<dynamic, dynamic>(3, "hello", "hello", 3);
+    self::A<core::int, core::String> a5 = new self::F::named<dynamic, dynamic>(3, "hello", "hello");
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..4c00155
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
@@ -0,0 +1,189 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<S extends core::Object, T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::A::S x;
+  generic-covariant-impl generic-covariant-interface field self::A::T y;
+  constructor •(self::A::S x, self::A::T y) → void
+    : self::A::x = x, self::A::y = y, super core::Object::•()
+    ;
+  constructor named(self::A::S x, self::A::T y) → void
+    : self::A::x = x, self::A::y = y, super core::Object::•()
+    ;
+}
+class B<S extends core::Object, T extends core::Object> extends self::A<self::B::T, self::B::S> {
+  constructor •(self::B::S y, self::B::T x) → void
+    : super self::A::•(x, y)
+    ;
+  constructor named(self::B::S y, self::B::T x) → void
+    : super self::A::named(x, y)
+    ;
+}
+class C<S extends core::Object> extends self::B<self::C::S, self::C::S> {
+  constructor •(self::C::S a) → void
+    : super self::B::•(a, a)
+    ;
+  constructor named(self::C::S a) → void
+    : super self::B::named(a, a)
+    ;
+}
+class D<S extends core::Object, T extends core::Object> extends self::B<self::D::T, core::int> {
+  constructor •(self::D::T a) → void
+    : super self::B::•(a, 3)
+    ;
+  constructor named(self::D::T a) → void
+    : super self::B::named(a, 3)
+    ;
+  abstract forwarding-stub set x(generic-covariant-impl core::int _) → void;
+}
+class E<S extends core::Object, T extends core::Object> extends self::A<self::C<self::E::S>, self::E::T> {
+  constructor •(self::E::T a) → void
+    : super self::A::•(null, a)
+    ;
+}
+class F<S extends core::Object, T extends core::Object> extends self::A<self::F::S, self::F::T> {
+  constructor •(self::F::S x, self::F::T y, {core::List<self::F::S> a = null, core::List<self::F::T> b = null}) → void
+    : super self::A::•(x, y)
+    ;
+  constructor named(self::F::S x, self::F::T y, [self::F::S a = null, self::F::T b = null]) → void
+    : super self::A::•(a, b)
+    ;
+}
+static method test() → void {
+  {
+    self::A<core::int, core::String> a0 = new self::A::•<core::int, core::String>(3, "hello");
+    self::A<core::int, core::String> a1 = new self::A::named<core::int, core::String>(3, "hello");
+    self::A<core::int, core::String> a2 = new self::A::•<core::int, core::String>(3, "hello");
+    self::A<core::int, core::String> a3 = new self::A::named<core::int, core::String>(3, "hello");
+    self::A<core::int, core::String> a4 = let final self::A<core::int, dynamic> #t1 = new self::A::•<core::int, dynamic>(3, "hello") in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:46:50: Error: The constructor returns type 'test::A<dart.core::int, dynamic>' that isn't of expected type 'test::A<dart.core::int, dart.core::String>'.
+Change the type of the object being constructed or the context in which it is used.
+        a4 = /*error:INVALID_CAST_NEW_EXPR*/ new A<int, dynamic>(3, \"hello\");
+                                                 ^";
+    self::A<core::int, core::String> a5 = let final self::A<dynamic, dynamic> #t2 = new self::A::named<dynamic, dynamic>(3, "hello") in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:48:50: Error: The constructor returns type 'test::A<dynamic, dynamic>' that isn't of expected type 'test::A<dart.core::int, dart.core::String>'.
+Change the type of the object being constructed or the context in which it is used.
+        a5 = /*error:INVALID_CAST_NEW_EXPR*/ new A<dynamic, dynamic>.named(
+                                                 ^";
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::A::•<core::int, core::String>(let final core::String #t3 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:53:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                               ^", let final core::int #t4 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:54:48: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
+                                               ^");
+    self::A<core::int, core::String> a1 = new self::A::named<core::int, core::String>(let final core::String #t5 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:56:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                               ^", let final core::int #t6 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:57:48: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
+                                               ^");
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::B::•<core::String, core::int>("hello", 3);
+    self::A<core::int, core::String> a1 = new self::B::named<core::String, core::int>("hello", 3);
+    self::A<core::int, core::String> a2 = new self::B::•<core::String, core::int>("hello", 3);
+    self::A<core::int, core::String> a3 = new self::B::named<core::String, core::int>("hello", 3);
+    self::A<core::int, core::String> a4 = let final self::B<core::String, dynamic> #t7 = new self::B::•<core::String, dynamic>("hello", 3) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:65:47: Error: A value of type 'test::B<dart.core::String, dynamic>' can't be assigned to a variable of type 'test::A<dart.core::int, dart.core::String>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A<dart.core::int, dart.core::String>'.
+        a4 = /*error:INVALID_ASSIGNMENT*/ new B<String, dynamic>(\"hello\", 3);
+                                              ^";
+    self::A<core::int, core::String> a5 = let final self::B<dynamic, dynamic> #t8 = new self::B::named<dynamic, dynamic>("hello", 3) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:67:47: Error: A value of type 'test::B<dynamic, dynamic>' can't be assigned to a variable of type 'test::A<dart.core::int, dart.core::String>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A<dart.core::int, dart.core::String>'.
+        a5 = /*error:INVALID_ASSIGNMENT*/ new B<dynamic, dynamic>.named(
+                                              ^";
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::B::•<core::String, core::int>(let final core::int #t9 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:72:48: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
+                                               ^", let final core::String #t10 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:73:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
+                                               ^");
+    self::A<core::int, core::String> a1 = new self::B::named<core::String, core::int>(let final core::int #t11 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:75:48: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3,
+                                               ^", let final core::String #t12 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:76:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
+                                               ^");
+  }
+  {
+    self::A<core::int, core::int> a0 = new self::C::•<core::int>(3);
+    self::A<core::int, core::int> a1 = new self::C::named<core::int>(3);
+    self::A<core::int, core::int> a2 = new self::C::•<core::int>(3);
+    self::A<core::int, core::int> a3 = new self::C::named<core::int>(3);
+    self::A<core::int, core::int> a4 = let final self::C<dynamic> #t13 = new self::C::•<dynamic>(3) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:83:55: Error: A value of type 'test::C<dynamic>' can't be assigned to a variable of type 'test::A<dart.core::int, dart.core::int>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A<dart.core::int, dart.core::int>'.
+    A<int, int> a4 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>(3);
+                                                      ^";
+    self::A<core::int, core::int> a5 = let final self::C<dynamic> #t14 = new self::C::named<dynamic>(3) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:84:55: Error: A value of type 'test::C<dynamic>' can't be assigned to a variable of type 'test::A<dart.core::int, dart.core::int>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A<dart.core::int, dart.core::int>'.
+    A<int, int> a5 = /*error:INVALID_ASSIGNMENT*/ new C<dynamic>.named(3);
+                                                      ^";
+  }
+  {
+    self::A<core::int, core::int> a0 = new self::C::•<core::int>(let final core::String #t15 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:88:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
+                                               ^");
+    self::A<core::int, core::int> a1 = new self::C::named<core::int>(let final core::String #t16 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:90:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
+                                               ^");
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::D::•<dynamic, core::String>("hello");
+    self::A<core::int, core::String> a1 = new self::D::named<dynamic, core::String>("hello");
+    self::A<core::int, core::String> a2 = new self::D::•<core::int, core::String>("hello");
+    self::A<core::int, core::String> a3 = new self::D::named<core::String, core::String>("hello");
+    self::A<core::int, core::String> a4 = let final self::D<core::num, dynamic> #t17 = new self::D::•<core::num, dynamic>("hello") in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:98:47: Error: A value of type 'test::D<dart.core::num, dynamic>' can't be assigned to a variable of type 'test::A<dart.core::int, dart.core::String>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A<dart.core::int, dart.core::String>'.
+        a4 = /*error:INVALID_ASSIGNMENT*/ new D<num, dynamic>(\"hello\");
+                                              ^";
+    self::A<core::int, core::String> a5 = let final self::D<dynamic, dynamic> #t18 = new self::D::named<dynamic, dynamic>("hello") in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:100:47: Error: A value of type 'test::D<dynamic, dynamic>' can't be assigned to a variable of type 'test::A<dart.core::int, dart.core::String>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A<dart.core::int, dart.core::String>'.
+        a5 = /*error:INVALID_ASSIGNMENT*/ new D<dynamic, dynamic>.named(
+                                              ^";
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::D::•<dynamic, core::String>(let final core::int #t19 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:105:48: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
+                                               ^");
+    self::A<core::int, core::String> a1 = new self::D::named<dynamic, core::String>(let final core::int #t20 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:107:48: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
+                                               ^");
+  }
+  {
+    self::A<self::C<core::int>, core::String> a0 = new self::E::•<core::int, core::String>("hello");
+  }
+  {
+    self::A<core::int, core::String> a0 = new self::F::•<core::int, core::String>(3, "hello", a: <core::int>[3], b: <core::String>["hello"]);
+    self::A<core::int, core::String> a1 = new self::F::•<core::int, core::String>(3, "hello", a: <core::int>[let final core::String #t21 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:118:54: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+          /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
+                                                     ^"], b: <core::String>[let final core::int #t22 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:121:54: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+          /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 3
+                                                     ^"]);
+    self::A<core::int, core::String> a2 = new self::F::named<core::int, core::String>(3, "hello", 3, "hello");
+    self::A<core::int, core::String> a3 = new self::F::named<core::int, core::String>(3, "hello");
+    self::A<core::int, core::String> a4 = new self::F::named<core::int, core::String>(3, "hello", let final core::String #t23 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:129:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                               ^", let final core::int #t24 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:130:48: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 3);
+                                               ^");
+    self::A<core::int, core::String> a5 = new self::F::named<core::int, core::String>(3, "hello", let final core::String #t25 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart:134:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+        /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\");
+                                               ^");
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..764ed07
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.direct.transformed.expect
@@ -0,0 +1,37 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method foo([core::List<core::String> list1 = const <dynamic>[], core::List<core::String> list2 = const <dynamic>[42]]) → void {}
+static method main() → void {
+  {
+    core::List<core::int> l0 = <dynamic>[];
+    core::List<core::int> l1 = <dynamic>[3];
+    core::List<core::int> l2 = <dynamic>["hello"];
+    core::List<core::int> l3 = <dynamic>["hello", 3];
+  }
+  {
+    core::List<dynamic> l0 = <dynamic>[];
+    core::List<dynamic> l1 = <dynamic>[3];
+    core::List<dynamic> l2 = <dynamic>["hello"];
+    core::List<dynamic> l3 = <dynamic>["hello", 3];
+  }
+  {
+    core::List<core::int> l0 = <core::num>[];
+    core::List<core::int> l1 = <core::num>[3];
+    core::List<core::int> l2 = <core::num>["hello"];
+    core::List<core::int> l3 = <core::num>["hello", 3];
+  }
+  {
+    core::Iterable<core::int> i0 = <dynamic>[];
+    core::Iterable<core::int> i1 = <dynamic>[3];
+    core::Iterable<core::int> i2 = <dynamic>["hello"];
+    core::Iterable<core::int> i3 = <dynamic>["hello", 3];
+  }
+  {
+    const core::List<core::int> c0 = const <dynamic>[];
+    const core::List<core::int> c1 = const <dynamic>[3];
+    const core::List<core::int> c2 = const <dynamic>["hello"];
+    const core::List<core::int> c3 = const <dynamic>["hello", 3];
+  }
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..f2d123f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart.strong.transformed.expect
@@ -0,0 +1,76 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method foo([core::List<core::String> list1 = const <core::String>[], core::List<core::String> list2 = const <core::String>[let final core::int #t1 = 42 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:11:89: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42
+                                                                                        ^"]]) → void {}
+static method main() → void {
+  {
+    core::List<core::int> l0 = <core::int>[];
+    core::List<core::int> l1 = <core::int>[3];
+    core::List<core::int> l2 = <core::int>[let final core::String #t2 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:19:50: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
+                                                 ^"];
+    core::List<core::int> l3 = <core::int>[let final core::String #t3 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:22:50: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                                 ^", 3];
+  }
+  {
+    core::List<dynamic> l0 = <dynamic>[];
+    core::List<dynamic> l1 = <dynamic>[3];
+    core::List<dynamic> l2 = <dynamic>["hello"];
+    core::List<dynamic> l3 = <dynamic>["hello", 3];
+  }
+  {
+    core::List<core::int> l0 = let final core::List<core::num> #t4 = <core::num>[] in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:33:61: Error: The list literal type 'dart.core::List<dart.core::num>' isn't of expected type 'dart.core::List<dart.core::int>'.
+Change the type of the list literal or the context in which it is used.
+    List<int> l0 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[];
+                                                            ^";
+    core::List<core::int> l1 = let final core::List<core::num> #t5 = <core::num>[3] in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:34:61: Error: The list literal type 'dart.core::List<dart.core::num>' isn't of expected type 'dart.core::List<dart.core::int>'.
+Change the type of the list literal or the context in which it is used.
+    List<int> l1 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[3];
+                                                            ^";
+    core::List<core::int> l2 = let final core::List<core::num> #t6 = <core::num>[let final core::String #t7 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:36:50: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::num'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::num'.
+      /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
+                                                 ^"] in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:35:61: Error: The list literal type 'dart.core::List<dart.core::num>' isn't of expected type 'dart.core::List<dart.core::int>'.
+Change the type of the list literal or the context in which it is used.
+    List<int> l2 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[
+                                                            ^";
+    core::List<core::int> l3 = let final core::List<core::num> #t8 = <core::num>[let final core::String #t9 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:39:50: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::num'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::num'.
+      /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                                 ^", 3] in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:38:61: Error: The list literal type 'dart.core::List<dart.core::num>' isn't of expected type 'dart.core::List<dart.core::int>'.
+Change the type of the list literal or the context in which it is used.
+    List<int> l3 = /*error:INVALID_CAST_LITERAL_LIST*/ <num>[
+                                                            ^";
+  }
+  {
+    core::Iterable<core::int> i0 = <core::int>[];
+    core::Iterable<core::int> i1 = <core::int>[3];
+    core::Iterable<core::int> i2 = <core::int>[let final core::String #t10 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:47:50: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
+                                                 ^"];
+    core::Iterable<core::int> i3 = <core::int>[let final core::String #t11 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:50:50: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                                 ^", 3];
+  }
+  {
+    const core::List<core::int> c0 = const <core::int>[];
+    const core::List<core::int> c1 = const <core::int>[3];
+    const core::List<core::int> c2 = const <core::int>[let final core::String #t12 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:58:89: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\"
+                                                                                        ^"];
+    const core::List<core::int> c3 = const <core::int>[let final core::String #t13 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_downwards.dart:61:89: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ \"hello\",
+                                                                                        ^", 3];
+  }
+}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.direct.transformed.expect
new file mode 100644
index 0000000..85ea052
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.direct.transformed.expect
@@ -0,0 +1,61 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef Asserter<T extends core::Object> = (T) → void;
+typedef AsserterBuilder<S extends core::Object, T extends core::Object> = (S) → (T) → void;
+class DartType extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class C extends core::Object {
+  static field (core::List<(self::DartType) → void>) → (self::DartType) → void assertBOf = null;
+  field (core::List<(self::DartType) → void>) → (self::DartType) → void assertAOf = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static get assertCOf() → (core::List<(self::DartType) → void>) → (self::DartType) → void
+    return null;
+  abstract get assertDOf() → (core::List<(self::DartType) → void>) → (self::DartType) → void;
+  method method((core::List<(self::DartType) → void>) → (self::DartType) → void assertEOf) → dynamic {
+    this.assertAOf(<dynamic>[self::_isInt, self::_isString]);
+    self::C::assertBOf.call(<dynamic>[self::_isInt, self::_isString]);
+    self::C::assertCOf.call(<dynamic>[self::_isInt, self::_isString]);
+    this.{self::C::assertDOf}(<dynamic>[self::_isInt, self::_isString]);
+    assertEOf.call(<dynamic>[self::_isInt, self::_isString]);
+  }
+}
+abstract class G<T extends core::Object> extends core::Object {
+  field (core::List<(self::DartType) → void>) → (self::DartType) → void assertAOf = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get assertDOf() → (core::List<(self::DartType) → void>) → (self::DartType) → void;
+  method method((core::List<(self::DartType) → void>) → (self::DartType) → void assertEOf) → dynamic {
+    this.assertAOf(<dynamic>[self::_isInt, self::_isString]);
+    this.{self::G::assertAOf}(<dynamic>[self::_isInt, self::_isString]);
+    this.{self::G::assertDOf}(<dynamic>[self::_isInt, self::_isString]);
+    assertEOf.call(<dynamic>[self::_isInt, self::_isString]);
+  }
+}
+static field (self::DartType) → void _isInt;
+static field (self::DartType) → void _isString;
+static field (core::List<(self::DartType) → void>) → (self::DartType) → void assertBOf;
+static get assertCOf() → (core::List<(self::DartType) → void>) → (self::DartType) → void
+  return null;
+static method test() → dynamic {
+  (core::List<(self::DartType) → void>) → (self::DartType) → void assertAOf;
+  assertAOf.call(<dynamic>[self::_isInt, self::_isString]);
+  self::assertBOf.call(<dynamic>[self::_isInt, self::_isString]);
+  self::assertCOf.call(<dynamic>[self::_isInt, self::_isString]);
+  self::C::assertBOf.call(<dynamic>[self::_isInt, self::_isString]);
+  self::C::assertCOf.call(<dynamic>[self::_isInt, self::_isString]);
+  self::C c;
+  c.assertAOf(<dynamic>[self::_isInt, self::_isString]);
+  c.assertDOf(<dynamic>[self::_isInt, self::_isString]);
+  self::G<core::int> g;
+  g.assertAOf(<dynamic>[self::_isInt, self::_isString]);
+  g.assertDOf(<dynamic>[self::_isInt, self::_isString]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.transformed.expect
new file mode 100644
index 0000000..3339b4b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_list_literals_infer_if_value_types_match_context.dart.strong.transformed.expect
@@ -0,0 +1,61 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef Asserter<T extends core::Object> = (T) → void;
+typedef AsserterBuilder<S extends core::Object, T extends core::Object> = (S) → (T) → void;
+class DartType extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class C extends core::Object {
+  static field (core::List<(self::DartType) → void>) → (self::DartType) → void assertBOf = null;
+  field (core::List<(self::DartType) → void>) → (self::DartType) → void assertAOf = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static get assertCOf() → (core::List<(self::DartType) → void>) → (self::DartType) → void
+    return null;
+  abstract get assertDOf() → (core::List<(self::DartType) → void>) → (self::DartType) → void;
+  method method((core::List<(self::DartType) → void>) → (self::DartType) → void assertEOf) → dynamic {
+    this.{self::C::assertAOf}(<(self::DartType) → void>[self::_isInt, self::_isString]);
+    self::C::assertBOf.call(<(self::DartType) → void>[self::_isInt, self::_isString]);
+    self::C::assertCOf.call(<(self::DartType) → void>[self::_isInt, self::_isString]);
+    this.{self::C::assertDOf}(<(self::DartType) → void>[self::_isInt, self::_isString]);
+    assertEOf.call(<(self::DartType) → void>[self::_isInt, self::_isString]);
+  }
+}
+abstract class G<T extends core::Object> extends core::Object {
+  field (core::List<(self::DartType) → void>) → (self::DartType) → void assertAOf = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get assertDOf() → (core::List<(self::DartType) → void>) → (self::DartType) → void;
+  method method((core::List<(self::DartType) → void>) → (self::DartType) → void assertEOf) → dynamic {
+    this.{self::G::assertAOf}(<(self::DartType) → void>[self::_isInt, self::_isString]);
+    this.{self::G::assertAOf}(<(self::DartType) → void>[self::_isInt, self::_isString]);
+    this.{self::G::assertDOf}(<(self::DartType) → void>[self::_isInt, self::_isString]);
+    assertEOf.call(<(self::DartType) → void>[self::_isInt, self::_isString]);
+  }
+}
+static field (self::DartType) → void _isInt;
+static field (self::DartType) → void _isString;
+static field (core::List<(self::DartType) → void>) → (self::DartType) → void assertBOf;
+static get assertCOf() → (core::List<(self::DartType) → void>) → (self::DartType) → void
+  return null;
+static method test() → dynamic {
+  (core::List<(self::DartType) → void>) → (self::DartType) → void assertAOf;
+  assertAOf.call(<(self::DartType) → void>[self::_isInt, self::_isString]);
+  self::assertBOf.call(<(self::DartType) → void>[self::_isInt, self::_isString]);
+  self::assertCOf.call(<(self::DartType) → void>[self::_isInt, self::_isString]);
+  self::C::assertBOf.call(<(self::DartType) → void>[self::_isInt, self::_isString]);
+  self::C::assertCOf.call(<(self::DartType) → void>[self::_isInt, self::_isString]);
+  self::C c;
+  c.{self::C::assertAOf}(<(self::DartType) → void>[self::_isInt, self::_isString]);
+  c.{self::C::assertDOf}(<(self::DartType) → void>[self::_isInt, self::_isString]);
+  self::G<core::int> g;
+  g.{self::G::assertAOf}(<(self::DartType) → void>[self::_isInt, self::_isString]);
+  g.{self::G::assertDOf}(<(self::DartType) → void>[self::_isInt, self::_isString]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.direct.transformed.expect
new file mode 100644
index 0000000..57c74f5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.direct.transformed.expect
@@ -0,0 +1,48 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method foo([core::Map<core::int, core::String> m1 = const <dynamic, dynamic>{1: "hello"}, core::Map<core::int, core::String> m2 = const <dynamic, dynamic>{"hello": "world"}]) → void {}
+static method test() → void {
+  {
+    core::Map<core::int, core::String> l0 = <dynamic, dynamic>{};
+    core::Map<core::int, core::String> l1 = <dynamic, dynamic>{3: "hello"};
+    core::Map<core::int, core::String> l2 = <dynamic, dynamic>{"hello": "hello"};
+    core::Map<core::int, core::String> l3 = <dynamic, dynamic>{3: 3};
+    core::Map<core::int, core::String> l4 = <dynamic, dynamic>{3: "hello", "hello": 3};
+  }
+  {
+    core::Map<dynamic, dynamic> l0 = <dynamic, dynamic>{};
+    core::Map<dynamic, dynamic> l1 = <dynamic, dynamic>{3: "hello"};
+    core::Map<dynamic, dynamic> l2 = <dynamic, dynamic>{"hello": "hello"};
+    core::Map<dynamic, dynamic> l3 = <dynamic, dynamic>{3: 3};
+    core::Map<dynamic, dynamic> l4 = <dynamic, dynamic>{3: "hello", "hello": 3};
+  }
+  {
+    core::Map<dynamic, core::String> l0 = <dynamic, dynamic>{};
+    core::Map<dynamic, core::String> l1 = <dynamic, dynamic>{3: "hello"};
+    core::Map<dynamic, core::String> l2 = <dynamic, dynamic>{"hello": "hello"};
+    core::Map<dynamic, core::String> l3 = <dynamic, dynamic>{3: 3};
+    core::Map<dynamic, core::String> l4 = <dynamic, dynamic>{3: "hello", "hello": 3};
+  }
+  {
+    core::Map<core::int, dynamic> l0 = <dynamic, dynamic>{};
+    core::Map<core::int, dynamic> l1 = <dynamic, dynamic>{3: "hello"};
+    core::Map<core::int, dynamic> l2 = <dynamic, dynamic>{"hello": "hello"};
+    core::Map<core::int, dynamic> l3 = <dynamic, dynamic>{3: 3};
+    core::Map<core::int, dynamic> l4 = <dynamic, dynamic>{3: "hello", "hello": 3};
+  }
+  {
+    core::Map<core::int, core::String> l0 = <core::num, dynamic>{};
+    core::Map<core::int, core::String> l1 = <core::num, dynamic>{3: "hello"};
+    core::Map<core::int, core::String> l3 = <core::num, dynamic>{3: 3};
+  }
+  {
+    const core::Map<core::int, core::String> l0 = const <dynamic, dynamic>{};
+    const core::Map<core::int, core::String> l1 = const <dynamic, dynamic>{3: "hello"};
+    const core::Map<core::int, core::String> l2 = const <dynamic, dynamic>{"hello": "hello"};
+    const core::Map<core::int, core::String> l3 = const <dynamic, dynamic>{3: 3};
+    const core::Map<core::int, core::String> l4 = const <dynamic, dynamic>{3: "hello", "hello": 3};
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect
new file mode 100644
index 0000000..0669aef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart.strong.transformed.expect
@@ -0,0 +1,96 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method foo([core::Map<core::int, core::String> m1 = const <core::int, core::String>{1: "hello"}, core::Map<core::int, core::String> m2 = const <core::int, core::String>{let final core::String #t1 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:12:79: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
+                                                                              ^": "world"}]) → void {}
+static method test() → void {
+  {
+    core::Map<core::int, core::String> l0 = <core::int, core::String>{};
+    core::Map<core::int, core::String> l1 = <core::int, core::String>{3: "hello"};
+    core::Map<core::int, core::String> l2 = <core::int, core::String>{let final core::String #t2 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:20:45: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\": \"hello\"
+                                            ^": "hello"};
+    core::Map<core::int, core::String> l3 = <core::int, core::String>{3: let final core::int #t3 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:23:50: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+                                                 ^"};
+    core::Map<core::int, core::String> l4 = <core::int, core::String>{3: "hello", let final core::String #t4 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:27:45: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
+                                            ^": let final core::int #t5 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:28:51: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+          /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+                                                  ^"};
+  }
+  {
+    core::Map<dynamic, dynamic> l0 = <dynamic, dynamic>{};
+    core::Map<dynamic, dynamic> l1 = <dynamic, dynamic>{3: "hello"};
+    core::Map<dynamic, dynamic> l2 = <dynamic, dynamic>{"hello": "hello"};
+    core::Map<dynamic, dynamic> l3 = <dynamic, dynamic>{3: 3};
+    core::Map<dynamic, dynamic> l4 = <dynamic, dynamic>{3: "hello", "hello": 3};
+  }
+  {
+    core::Map<dynamic, core::String> l0 = <dynamic, core::String>{};
+    core::Map<dynamic, core::String> l1 = <dynamic, core::String>{3: "hello"};
+    core::Map<dynamic, core::String> l2 = <dynamic, core::String>{"hello": "hello"};
+    core::Map<dynamic, core::String> l3 = <dynamic, core::String>{3: let final core::int #t6 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:48:50: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+                                                 ^"};
+    core::Map<dynamic, core::String> l4 = <dynamic, core::String>{3: "hello", "hello": let final core::int #t7 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:52:56: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      \"hello\": /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+                                                       ^"};
+  }
+  {
+    core::Map<core::int, dynamic> l0 = <core::int, dynamic>{};
+    core::Map<core::int, dynamic> l1 = <core::int, dynamic>{3: "hello"};
+    core::Map<core::int, dynamic> l2 = <core::int, dynamic>{let final core::String #t8 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:59:45: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\": \"hello\"
+                                            ^": "hello"};
+    core::Map<core::int, dynamic> l3 = <core::int, dynamic>{3: 3};
+    core::Map<core::int, dynamic> l4 = <core::int, dynamic>{3: "hello", let final core::String #t9 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:64:45: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\": 3
+                                            ^": 3};
+  }
+  {
+    core::Map<core::int, core::String> l0 = let final core::Map<core::num, dynamic> #t10 = <core::num, dynamic>{} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:68:76: Error: The map literal type 'dart.core::Map<dart.core::num, dynamic>' isn't of expected type 'dart.core::Map<dart.core::int, dart.core::String>'.
+Change the type of the map literal or the context in which it is used.
+    Map<int, String> l0 = /*error:INVALID_CAST_LITERAL_MAP*/ <num, dynamic>{};
+                                                                           ^";
+    core::Map<core::int, core::String> l1 = let final core::Map<core::num, dynamic> #t11 = <core::num, dynamic>{3: "hello"} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:69:76: Error: The map literal type 'dart.core::Map<dart.core::num, dynamic>' isn't of expected type 'dart.core::Map<dart.core::int, dart.core::String>'.
+Change the type of the map literal or the context in which it is used.
+    Map<int, String> l1 = /*error:INVALID_CAST_LITERAL_MAP*/ <num, dynamic>{
+                                                                           ^";
+    core::Map<core::int, core::String> l3 = let final core::Map<core::num, dynamic> #t12 = <core::num, dynamic>{3: 3} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:72:76: Error: The map literal type 'dart.core::Map<dart.core::num, dynamic>' isn't of expected type 'dart.core::Map<dart.core::int, dart.core::String>'.
+Change the type of the map literal or the context in which it is used.
+    Map<int, String> l3 = /*error:INVALID_CAST_LITERAL_MAP*/ <num, dynamic>{
+                                                                           ^";
+  }
+  {
+    const core::Map<core::int, core::String> l0 = const <core::int, core::String>{};
+    const core::Map<core::int, core::String> l1 = const <core::int, core::String>{3: "hello"};
+    const core::Map<core::int, core::String> l2 = const <core::int, core::String>{let final core::String #t13 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:80:79: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
+                                                                              ^": "hello"};
+    const core::Map<core::int, core::String> l3 = const <core::int, core::String>{3: let final core::int #t14 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:84:86: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+      3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+                                                                                     ^"};
+    const core::Map<core::int, core::String> l4 = const <core::int, core::String>{3: "hello", let final core::String #t15 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:88:79: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ \"hello\":
+                                                                              ^": let final core::int #t16 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/downwards_inference_on_map_literals.dart:89:87: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+          /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/ 3
+                                                                                      ^"};
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.direct.transformed.expect
new file mode 100644
index 0000000..55bf544
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_yield_yield_star.dart.direct.transformed.expect
@@ -0,0 +1,81 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+abstract class MyStream<T extends core::Object> extends asy::Stream<self::MyStream::T> {
+  static factory •<T extends core::Object>() → self::MyStream<self::MyStream::•::T>
+    return null;
+}
+static method foo() → asy::Stream<core::List<core::int>> /* originally async* */ {
+  asy::_AsyncStarStreamController<core::List<core::int>> :controller;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L1:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}(<dynamic>[]))
+            return null;
+          else
+            [yield] null;
+          if(:controller.{asy::_AsyncStarStreamController::add}(self::MyStream::•<dynamic>()))
+            return null;
+          else
+            [yield] null;
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(<dynamic>[]))
+            return null;
+          else
+            [yield] null;
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(self::MyStream::•<dynamic>()))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<core::List<core::int>>(:async_op);
+  return :controller.{asy::_AsyncStarStreamController::stream};
+}
+static method bar() → core::Iterable<core::Map<core::int, core::int>> /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<core::Map<core::int, core::int>> :iterator) → core::bool yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = <dynamic, dynamic>{};
+        [yield] true;
+      }
+      {
+        :iterator.{core::_SyncIterator::_current} = core::List::•<dynamic>();
+        [yield] true;
+      }
+      {
+        :iterator.{core::_SyncIterator::_yieldEachIterable} = <dynamic, dynamic>{};
+        [yield] true;
+      }
+      {
+        :iterator.{core::_SyncIterator::_yieldEachIterable} = core::List::•<dynamic>();
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<core::Map<core::int, core::int>>(:sync_op);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.direct.transformed.expect
new file mode 100644
index 0000000..d6018e5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.direct.transformed.expect
@@ -0,0 +1,31 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(core::int x) → core::int
+    return x;
+}
+static method test() → dynamic {
+  dynamic d = new self::Foo::•();
+  dynamic get_hashCode = d.hashCode;
+  dynamic call_hashCode = d.hashCode();
+  dynamic call_toString = d.toString();
+  dynamic call_toStringArg = d.toString(color: "pink");
+  dynamic call_foo0 = d.foo();
+  dynamic call_foo1 = d.foo(1);
+  dynamic call_foo2 = d.foo(1, 2);
+  dynamic call_nsm0 = d.noSuchMethod();
+  dynamic call_nsm1 = d.noSuchMethod(null);
+  dynamic call_nsm2 = d.noSuchMethod(null, null);
+  dynamic equals_self = d.==(d);
+  dynamic equals_null = d.==(null);
+  dynamic null_equals = null.==(d);
+  dynamic not_equals_self = !d.==(d);
+  dynamic not_equals_null = !d.==(null);
+  dynamic null_not_equals = !null.==(d);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
new file mode 100644
index 0000000..97bedda
--- /dev/null
+++ b/pkg/front_end/testcases/inference/dynamic_methods.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(core::int x) → core::int
+    return x;
+}
+static method test() → dynamic {
+  dynamic d = new self::Foo::•();
+  dynamic get_hashCode = d.hashCode;
+  dynamic call_hashCode = d.hashCode();
+  dynamic call_toString = d.toString();
+  dynamic call_toStringArg = d.toString(color: "pink");
+  dynamic call_foo0 = d.foo();
+  dynamic call_foo1 = d.foo(1);
+  dynamic call_foo2 = d.foo(1, 2);
+  dynamic call_nsm0 = d.noSuchMethod();
+  dynamic call_nsm1 = d.noSuchMethod(null);
+  dynamic call_nsm2 = d.noSuchMethod(null, null);
+  core::bool equals_self = d.==(d);
+  core::bool equals_null = d.==(null);
+  core::bool null_equals = null.{core::Object::==}(d);
+  core::bool not_equals_self = !d.==(d);
+  core::bool not_equals_null = !d.==(null);
+  core::bool null_not_equals = !null.{core::Object::==}(d);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.direct.transformed.expect
new file mode 100644
index 0000000..a9ca0dd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field core::int x;
+  constructor •() → void
+    : self::C::x = self::f<dynamic>(), super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.strong.transformed.expect
new file mode 100644
index 0000000..8924797
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_explicit.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field core::int x;
+  constructor •() → void
+    : self::C::x = self::f<core::int>(), super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.direct.transformed.expect
new file mode 100644
index 0000000..d495b26
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object implements self::B {
+  final field dynamic x;
+  constructor •() → void
+    : self::C::x = self::f<dynamic>(), super core::Object::•()
+    ;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.strong.transformed.expect
new file mode 100644
index 0000000..ef576d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_implicit.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object implements self::B {
+  final field core::int x;
+  constructor •() → void
+    : self::C::x = self::f<core::int>(), super core::Object::•()
+    ;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_this.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.direct.transformed.expect
new file mode 100644
index 0000000..a9ca0dd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field core::int x;
+  constructor •() → void
+    : self::C::x = self::f<dynamic>(), super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_context_this.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.strong.transformed.expect
new file mode 100644
index 0000000..8924797
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_context_this.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field core::int x;
+  constructor •() → void
+    : self::C::x = self::f<core::int>(), super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_parameter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.direct.transformed.expect
new file mode 100644
index 0000000..dfabd77
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field dynamic x;
+  constructor •(core::int p) → void
+    : self::C::x = self::f<dynamic>(p), super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>(self::f::T t) → self::f::T
+  return t;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_initializer_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.strong.transformed.expect
new file mode 100644
index 0000000..ba6f581f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_initializer_parameter.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field dynamic x;
+  constructor •(core::int p) → void
+    : self::C::x = self::f<core::int>(p), super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>(self::f::T t) → self::f::T
+  return t;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.direct.transformed.expect
new file mode 100644
index 0000000..a520339
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field dynamic x = self::C::_x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static get _x() → core::int
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.strong.transformed.expect
new file mode 100644
index 0000000..00d0f7e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_static_getter.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field core::int x = self::C::_x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static get _x() → core::int
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.direct.transformed.expect
new file mode 100644
index 0000000..c0d8691
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field dynamic x = self::y;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static get y() → core::int
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.strong.transformed.expect
new file mode 100644
index 0000000..284721c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/field_refers_to_top_level_getter.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field core::int x = self::y;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static get y() → core::int
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.direct.transformed.expect
new file mode 100644
index 0000000..67e28bf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.direct.transformed.expect
@@ -0,0 +1,82 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        core::Object o;
+        for (dynamic x in o) {
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(o);
+          try
+            #L2:
+            while (true) {
+              [yield] let dynamic #t1 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L2;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        core::int y;
+        for (final dynamic #t3 in o) {
+          y = #t3;
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(o);
+          try
+            #L3:
+            while (true) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t5 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  y = #t5;
+                }
+              }
+              else
+                break #L3;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
new file mode 100644
index 0000000..3b987da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
@@ -0,0 +1,82 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        core::Object o;
+        for (dynamic x in o as{TypeError} core::Iterable<dynamic>) {
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(o as{TypeError} asy::Stream<dynamic>);
+          try
+            #L2:
+            while (true) {
+              [yield] let dynamic #t1 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L2;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        core::int y;
+        for (final dynamic #t3 in o as{TypeError} core::Iterable<dynamic>) {
+          y = #t3 as{TypeError} core::int;
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(o as{TypeError} asy::Stream<dynamic>);
+          try
+            #L3:
+            while (true) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t5 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  y = #t5 as{TypeError} core::int;
+                }
+              }
+              else
+                break #L3;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.direct.transformed.expect
new file mode 100644
index 0000000..666cfba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test(core::List<core::num> nums) → void {
+  for (dynamic x in nums) {
+    if(x is core::int) {
+      dynamic y = x{core::int};
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.strong.transformed.expect
new file mode 100644
index 0000000..807a04e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_in_loop_promotion.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test(core::List<core::num> nums) → void {
+  for (core::num x in nums) {
+    if(x is core::int) {
+      core::int y = x{core::int};
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.direct.transformed.expect
new file mode 100644
index 0000000..9f73c0c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  #L1:
+  for (core::num x = 0; ; x = x.+(1)) {
+    if(x.>=(10))
+      break #L1;
+    if(x is core::int) {
+      dynamic y = x{core::int};
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.strong.transformed.expect
new file mode 100644
index 0000000..ab19183
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_empty_condition.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  #L1:
+  for (core::num x = 0; ; x = x.{core::num::+}(1)) {
+    if(x.{core::num::>=}(10))
+      break #L1;
+    if(x is core::int) {
+      core::int y = x{core::int};
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.direct.transformed.expect
new file mode 100644
index 0000000..2ae6220
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::num x;
+  for (final dynamic #t1 = x = 0; x.<(10); x = x.+(1)) {
+    if(x is core::int) {
+      dynamic y = x{core::int};
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.strong.transformed.expect
new file mode 100644
index 0000000..dd4258d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_initializer_expression.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::num x;
+  for (final dynamic #t1 = x = 0; x.{core::num::<}(10); x = x.{core::num::+}(1)) {
+    if(x is core::int) {
+      core::int y = x{core::int};
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_loop_promotion.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/for_loop_promotion.dart.direct.transformed.expect
new file mode 100644
index 0000000..8edae6d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_promotion.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  for (core::num x = 0; x.<(10); x = x.+(1)) {
+    if(x is core::int) {
+      dynamic y = x{core::int};
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/for_loop_promotion.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/for_loop_promotion.dart.strong.transformed.expect
new file mode 100644
index 0000000..e62a156
--- /dev/null
+++ b/pkg/front_end/testcases/inference/for_loop_promotion.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  for (core::num x = 0; x.{core::num::<}(10); x = x.{core::num::+}(1)) {
+    if(x is core::int) {
+      core::int y = x{core::int};
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_or_subtyping.dart.direct.transformed.expect
new file mode 100644
index 0000000..2654b7e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method add(core::int x) → void {}
+static method add2(core::int y) → dynamic {}
+static method test() → dynamic {
+  asy::Future<core::int> f;
+  dynamic a = f.then(self::add);
+  dynamic b = f.then(self::add2);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.transformed.expect
new file mode 100644
index 0000000..4f6fa47
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_or_subtyping.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method add(core::int x) → void {}
+static method add2(core::int y) → dynamic {}
+static method test() → dynamic {
+  asy::Future<core::int> f;
+  asy::Future<void> a = f.{asy::Future::then}<void>(self::add);
+  asy::Future<dynamic> b = f.{asy::Future::then}<dynamic>(self::add2);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
new file mode 100644
index 0000000..2ea9110
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then.dart.direct.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<dynamic> f;
+  asy::Future<core::int> t1 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t3 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t4 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.then((dynamic _) → dynamic => asy::Future::value<core::int>(3));
+  asy::Future<core::int> t6 = f.then((dynamic _) → dynamic {
+    return asy::Future::value<core::int>(3);
+  });
+  asy::Future<core::int> t7 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t8 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
new file mode 100644
index 0000000..82803df
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<dynamic> f;
+  asy::Future<core::int> t1 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t3 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t4 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(3));
+  asy::Future<core::int> t6 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> {
+    return asy::Future::value<core::int>(3);
+  });
+  asy::Future<core::int> t7 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t8 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..920eb54
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.direct.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<dynamic> f;
+  asy::Future<core::int> t1 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t3 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t4 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.then((dynamic _) → dynamic => new self::MyFuture::value<core::int>(3));
+  asy::Future<core::int> t6 = f.then((dynamic _) → dynamic {
+    return new self::MyFuture::value<core::int>(3);
+  });
+  asy::Future<core::int> t7 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t8 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..abf3ad2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<dynamic> f;
+  asy::Future<core::int> t1 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t3 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t4 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>(3));
+  asy::Future<core::int> t6 = f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> {
+    return new self::MyFuture::value<core::int>(3);
+  });
+  asy::Future<core::int> t7 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t8 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
new file mode 100644
index 0000000..752fb03
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.direct.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<dynamic> f;
+  self::MyFuture<core::int> t1 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t2 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t3 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t4 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t5 = f.then((dynamic _) → dynamic => asy::Future::value<core::int>(3));
+  self::MyFuture<core::int> t6 = f.then((dynamic _) → dynamic {
+    return asy::Future::value<core::int>(3);
+  });
+  self::MyFuture<core::int> t7 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t8 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
new file mode 100644
index 0000000..2678694
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<dynamic> f;
+  self::MyFuture<core::int> t1 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t2 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t3 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t4 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t5 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(3));
+  self::MyFuture<core::int> t6 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> {
+    return asy::Future::value<core::int>(3);
+  });
+  self::MyFuture<core::int> t7 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t8 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
new file mode 100644
index 0000000..c1da628
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.direct.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<dynamic> f;
+  self::MyFuture<core::int> t1 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t2 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t3 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t4 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t5 = f.then((dynamic _) → dynamic => new self::MyFuture::value<core::int>(3));
+  self::MyFuture<core::int> t6 = f.then((dynamic _) → dynamic {
+    return new self::MyFuture::value<core::int>(3);
+  });
+  self::MyFuture<core::int> t7 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t8 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
new file mode 100644
index 0000000..4b747e7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<dynamic> f;
+  self::MyFuture<core::int> t1 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t2 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t3 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t4 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t5 = f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>(3));
+  self::MyFuture<core::int> t6 = f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> {
+    return new self::MyFuture::value<core::int>(3);
+  });
+  self::MyFuture<core::int> t7 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t8 = f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
new file mode 100644
index 0000000..e7a0114
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.direct.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  asy::Future<dynamic> f;
+  asy::Future<core::int> t1 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t3 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t4 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.then((dynamic _) → dynamic => new self::MyFuture::value<core::int>(3));
+  asy::Future<core::int> t6 = f.then((dynamic _) → dynamic {
+    return new self::MyFuture::value<core::int>(3);
+  });
+  asy::Future<core::int> t7 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t8 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
new file mode 100644
index 0000000..e8a77dc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  asy::Future<dynamic> f;
+  asy::Future<core::int> t1 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t3 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t4 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.{asy::Future::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>(3));
+  asy::Future<core::int> t6 = f.{asy::Future::then}<core::int>((dynamic _) → self::MyFuture<core::int> {
+    return new self::MyFuture::value<core::int>(3);
+  });
+  asy::Future<core::int> t7 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t8 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = new self::MyFuture::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
new file mode 100644
index 0000000..c04938b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.direct.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  asy::Future<dynamic> f;
+  asy::Future<core::int> t1 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t3 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t4 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.then((dynamic _) → dynamic => asy::Future::value<core::int>(3));
+  asy::Future<core::int> t6 = f.then((dynamic _) → dynamic {
+    return asy::Future::value<core::int>(3);
+  });
+  asy::Future<core::int> t7 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t8 = f.then((dynamic _) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
new file mode 100644
index 0000000..fba912b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
@@ -0,0 +1,188 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  asy::Future<dynamic> f;
+  asy::Future<core::int> t1 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t3 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = 3;
+          break #L3;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t4 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = 3;
+          break #L4;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(3));
+  asy::Future<core::int> t6 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> {
+    return asy::Future::value<core::int>(3);
+  });
+  asy::Future<core::int> t7 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L5;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t8 = f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L6:
+        {
+          :return_value = asy::Future::value<core::int>(3);
+          break #L6;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
new file mode 100644
index 0000000..61e4088
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.direct.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<core::bool> f;
+  asy::Future<core::int> t1 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result ? 2 : asy::Future::value<core::int>(3);
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.then((dynamic x) → dynamic => x ? 2 : asy::Future::value<core::int>(3));
+  asy::Future<core::int> t6 = f.then((dynamic x) → dynamic {
+    return x ? 2 : asy::Future::value<core::int>(3);
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
new file mode 100644
index 0000000..d83bae2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<core::bool> f;
+  asy::Future<core::int> t1 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = (:result ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::FutureOr<core::int> => (x ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>);
+  asy::Future<core::int> t6 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::FutureOr<core::int> {
+    return (x ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..bc86cdc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.direct.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<core::bool> f;
+  asy::Future<core::int> t1 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result ? 2 : new self::MyFuture::value<core::int>(3);
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.then((dynamic x) → dynamic => x ? 2 : new self::MyFuture::value<core::int>(3));
+  asy::Future<core::int> t6 = f.then((dynamic x) → dynamic {
+    return x ? 2 : new self::MyFuture::value<core::int>(3);
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..27c0cd2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<core::bool> f;
+  asy::Future<core::int> t1 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = (:result ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::FutureOr<core::int> => (x ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>);
+  asy::Future<core::int> t6 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::FutureOr<core::int> {
+    return (x ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
new file mode 100644
index 0000000..88cca73
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.direct.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<core::bool> f;
+  self::MyFuture<core::int> t1 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t2 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result ? 2 : asy::Future::value<core::int>(3);
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t5 = f.then((dynamic x) → dynamic => x ? 2 : asy::Future::value<core::int>(3));
+  self::MyFuture<core::int> t6 = f.then((dynamic x) → dynamic {
+    return x ? 2 : asy::Future::value<core::int>(3);
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
new file mode 100644
index 0000000..008dad4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<core::bool> f;
+  self::MyFuture<core::int> t1 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t2 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = (:result ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t5 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::FutureOr<core::int> => (x ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>);
+  self::MyFuture<core::int> t6 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::FutureOr<core::int> {
+    return (x ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
new file mode 100644
index 0000000..c248a6d3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.direct.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<core::bool> f;
+  self::MyFuture<core::int> t1 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t2 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result ? 2 : new self::MyFuture::value<core::int>(3);
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t5 = f.then((dynamic x) → dynamic => x ? 2 : new self::MyFuture::value<core::int>(3));
+  self::MyFuture<core::int> t6 = f.then((dynamic x) → dynamic {
+    return x ? 2 : new self::MyFuture::value<core::int>(3);
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
new file mode 100644
index 0000000..5db216e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<core::bool> f;
+  self::MyFuture<core::int> t1 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t2 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = (:result ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  self::MyFuture<core::int> t5 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::FutureOr<core::int> => (x ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>);
+  self::MyFuture<core::int> t6 = f.{self::MyFuture::then}<core::int>((core::bool x) → asy::FutureOr<core::int> {
+    return (x ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
new file mode 100644
index 0000000..eb4fbef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.direct.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  asy::Future<core::bool> f;
+  asy::Future<core::int> t1 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result ? 2 : new self::MyFuture::value<core::int>(3);
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.then((dynamic x) → dynamic => x ? 2 : new self::MyFuture::value<core::int>(3));
+  asy::Future<core::int> t6 = f.then((dynamic x) → dynamic {
+    return x ? 2 : new self::MyFuture::value<core::int>(3);
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
new file mode 100644
index 0000000..4ab3d5f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  asy::Future<core::bool> f;
+  asy::Future<core::int> t1 = f.{asy::Future::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(new self::MyFuture::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.{asy::Future::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = (:result ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.{asy::Future::then}<core::int>((core::bool x) → asy::FutureOr<core::int> => (x ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>);
+  asy::Future<core::int> t6 = f.{asy::Future::then}<core::int>((core::bool x) → asy::FutureOr<core::int> {
+    return (x ?{core::Object} 2 : new self::MyFuture::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
new file mode 100644
index 0000000..ca97197
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.direct.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  asy::Future<core::bool> f;
+  asy::Future<core::int> t1 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = :result ? 2 : asy::Future::value<core::int>(3);
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.then((dynamic x) → dynamic => x ? 2 : asy::Future::value<core::int>(3));
+  asy::Future<core::int> t6 = f.then((dynamic x) → dynamic {
+    return x ? 2 : asy::Future::value<core::int>(3);
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
new file mode 100644
index 0000000..14029ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
@@ -0,0 +1,87 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  asy::Future<core::bool> f;
+  asy::Future<core::int> t1 = f.{asy::Future::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          if(x) {
+            :async_temporary_0 = 2;
+          }
+          else {
+            [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.{asy::Future::then}<core::int>((core::bool x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t2 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = (:result ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.{asy::Future::then}<core::int>((core::bool x) → asy::FutureOr<core::int> => (x ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>);
+  asy::Future<core::int> t6 = f.{asy::Future::then}<core::int>((core::bool x) → asy::FutureOr<core::int> {
+    return (x ?{core::Object} 2 : asy::Future::value<core::int>(3)) as{TypeError} asy::FutureOr<core::int>;
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.direct.transformed.expect
new file mode 100644
index 0000000..5c1094c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  asy::Future<core::int> f;
+  asy::Future<core::List<core::int>> b = f.then((dynamic x) → dynamic => <dynamic>[]).whenComplete(() → dynamic {});
+  b = f.then((dynamic x) → dynamic => <dynamic>[]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect
new file mode 100644
index 0000000..ce86786
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_downwards_method_target.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  asy::Future<core::int> f;
+  asy::Future<core::List<core::int>> b = f.{asy::Future::then}<core::List<dynamic>>((core::int x) → core::List<dynamic> => <dynamic>[]).{asy::Future::whenComplete}(() → core::Null {}) as{TypeError} asy::Future<core::List<core::int>>;
+  b = f.{asy::Future::then}<core::List<core::int>>((core::int x) → core::List<core::int> => <core::int>[]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
new file mode 100644
index 0000000..98e506f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.direct.transformed.expect
@@ -0,0 +1,88 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<core::int> f;
+  asy::Future<core::int> t1 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          final dynamic #t1 = x;
+          if(#t1.==(null)) {
+            [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          else {
+            :async_temporary_0 = #t1;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.then((dynamic x) → asy::Future<dynamic> /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t3 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = let final dynamic #t4 = :result in #t4.==(null) ? asy::Future::value<core::int>(3) : #t4;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.then((dynamic x) → dynamic => let final dynamic #t5 = x in #t5.==(null) ? asy::Future::value<core::int>(3) : #t5);
+  asy::Future<core::int> t6 = f.then((dynamic x) → dynamic {
+    return let final dynamic #t6 = x in #t6.==(null) ? asy::Future::value<core::int>(3) : #t6;
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
new file mode 100644
index 0000000..c0b8a92
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
@@ -0,0 +1,88 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  self::MyFuture<core::int> f;
+  asy::Future<core::int> t1 = f.{self::MyFuture::then}<core::int>((core::int x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :async_temporary_0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          final core::int #t1 = x;
+          if(#t1.==(null)) {
+            [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::int>(3), :async_op_then, :async_op_error, :async_op) in null;
+            :async_temporary_0 = :result;
+          }
+          else {
+            :async_temporary_0 = #t1;
+          }
+          :return_value = :async_temporary_0;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t2 = f.{self::MyFuture::then}<core::int>((core::int x) → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          [yield] let dynamic #t3 = asy::_awaitHelper(x, :async_op_then, :async_op_error, :async_op) in null;
+          :return_value = (let final core::int #t4 = :result in #t4.==(null) ?{core::Object} asy::Future::value<core::int>(3) : #t4) as{TypeError} asy::FutureOr<core::int>;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  });
+  asy::Future<core::int> t5 = f.{self::MyFuture::then}<core::int>((core::int x) → asy::FutureOr<core::int> => (let final core::int #t5 = x in #t5.==(null) ?{core::Object} asy::Future::value<core::int>(3) : #t5) as{TypeError} asy::FutureOr<core::int>);
+  asy::Future<core::int> t6 = f.{self::MyFuture::then}<core::int>((core::int x) → asy::FutureOr<core::int> {
+    return (let final core::int #t6 = x in #t6.==(null) ?{core::Object} asy::Future::value<core::int>(3) : #t6) as{TypeError} asy::FutureOr<core::int>;
+  });
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..ef2dc93
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method main() → void {
+  dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
+  asy::Future<core::int> f2 = f;
+  asy::Future<core::num> f3 = self::foo().then((dynamic _) → dynamic => 2.3) as asy::Future<core::double>;
+}
+static method foo() → self::MyFuture<dynamic>
+  return new self::MyFuture::value<core::int>(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..c6a2773
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method main() → void {
+  self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
+  asy::Future<core::int> f2 = let final self::MyFuture<core::double> #t1 = f in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_then_upwards.dart:21:49: Error: A value of type 'test::MyFuture<dart.core::double>' can't be assigned to a variable of type 'dart.async::Future<dart.core::int>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.async::Future<dart.core::int>'.
+  Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
+                                                ^";
+  asy::Future<core::num> f3 = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3) as asy::Future<core::double>;
+}
+static method foo() → self::MyFuture<dynamic>
+  return new self::MyFuture::value<core::int>(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..d4901ef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method main() → void {
+  dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
+  self::MyFuture<core::int> f2 = f;
+  self::MyFuture<core::num> f3 = self::foo().then((dynamic _) → dynamic => 2.3) as self::MyFuture<core::double>;
+}
+static method foo() → self::MyFuture<dynamic>
+  return new self::MyFuture::value<core::int>(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..8301b6c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_2.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method main() → void {
+  self::MyFuture<core::double> f = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3);
+  self::MyFuture<core::int> f2 = let final self::MyFuture<core::double> #t1 = f in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_then_upwards_2.dart:21:51: Error: A value of type 'test::MyFuture<dart.core::double>' can't be assigned to a variable of type 'test::MyFuture<dart.core::int>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::MyFuture<dart.core::int>'.
+  MyFuture<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
+                                                  ^";
+  self::MyFuture<core::num> f3 = self::foo().{self::MyFuture::then}<core::double>((dynamic _) → core::double => 2.3) as self::MyFuture<core::double>;
+}
+static method foo() → self::MyFuture<dynamic>
+  return new self::MyFuture::value<core::int>(1);
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
new file mode 100644
index 0000000..8be59eb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  dynamic f = self::foo().then((dynamic _) → dynamic => 2.3);
+  asy::Future<core::int> f2 = f;
+  asy::Future<core::num> f3 = self::foo().then((dynamic _) → dynamic => 2.3) as asy::Future<core::double>;
+}
+static method foo() → asy::Future<dynamic>
+  return asy::Future::value<core::int>(1);
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
new file mode 100644
index 0000000..bd5c8d5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_3.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(self::MyFuture::T x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method test() → void {
+  asy::Future<core::double> f = self::foo().{asy::Future::then}<core::double>((dynamic _) → core::double => 2.3);
+  asy::Future<core::int> f2 = let final asy::Future<core::double> #t1 = f in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_then_upwards_3.dart:21:49: Error: A value of type 'dart.async::Future<dart.core::double>' can't be assigned to a variable of type 'dart.async::Future<dart.core::int>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.async::Future<dart.core::int>'.
+  Future<int> f2 = /*error:INVALID_ASSIGNMENT*/ f;
+                                                ^";
+  asy::Future<core::num> f3 = self::foo().{asy::Future::then}<core::double>((dynamic _) → core::double => 2.3) as asy::Future<core::double>;
+}
+static method foo() → asy::Future<dynamic>
+  return asy::Future::value<core::int>(1);
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.direct.transformed.expect
new file mode 100644
index 0000000..799443c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  asy::Future<core::int> base;
+  dynamic f = base.then((dynamic x) → dynamic {
+    return x.==(0);
+  });
+  dynamic g = base.then((dynamic x) → dynamic => x.==(0));
+  asy::Future<core::bool> b = f;
+  b = g;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.transformed.expect
new file mode 100644
index 0000000..4c45b42
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_then_upwards_from_block.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  asy::Future<core::int> base;
+  asy::Future<core::bool> f = base.{asy::Future::then}<core::bool>((core::int x) → core::bool {
+    return x.{core::num::==}(0);
+  });
+  asy::Future<core::bool> g = base.{asy::Future::then}<core::bool>((core::int x) → core::bool => x.{core::num::==}(0));
+  asy::Future<core::bool> b = f;
+  b = g;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
new file mode 100644
index 0000000..911e233
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.direct.transformed.expect
@@ -0,0 +1,97 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(dynamic x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = x ? 42 : asy::Future::value<dynamic>(42);
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g2(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = x ? 42 : asy::Future::value<dynamic>(42);
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L3:
+      {
+        dynamic y = x ? 42 : asy::Future::value<dynamic>(42);
+        :return_value = y;
+        break #L3;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
new file mode 100644
index 0000000..7c803fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
@@ -0,0 +1,97 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(dynamic x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = (x ?{core::Object} 42 : asy::Future::value<core::int>(42)) as{TypeError} asy::FutureOr<core::int>;
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g2(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = (x ?{core::Object} 42 : asy::Future::value<core::int>(42)) as{TypeError} asy::FutureOr<core::int>;
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L3:
+      {
+        core::Object y = x ?{core::Object} 42 : asy::Future::value<core::int>(42);
+        :return_value = y as{TypeError} asy::FutureOr<core::int>;
+        break #L3;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..00559fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.direct.transformed.expect
@@ -0,0 +1,97 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(dynamic x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = x ? 42 : new self::MyFuture::value<dynamic>(42);
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g2(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = x ? 42 : new self::MyFuture::value<dynamic>(42);
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L3:
+      {
+        dynamic y = x ? 42 : new self::MyFuture::value<dynamic>(42);
+        :return_value = y;
+        break #L3;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..10fb0f8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
@@ -0,0 +1,97 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value(dynamic x) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static method g1(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = (x ?{core::Object} 42 : new self::MyFuture::value<core::int>(42)) as{TypeError} asy::FutureOr<core::int>;
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g2(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = (x ?{core::Object} 42 : new self::MyFuture::value<core::int>(42)) as{TypeError} asy::FutureOr<core::int>;
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3(core::bool x) → asy::Future<core::int> /* originally async */ {
+  final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+  asy::FutureOr<core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L3:
+      {
+        core::Object y = x ?{core::Object} 42 : new self::MyFuture::value<dynamic>(42);
+        :return_value = y as{TypeError} asy::FutureOr<core::int>;
+        break #L3;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..859cda9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.direct.transformed.expect
@@ -0,0 +1,72 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value([dynamic x = null]) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static field self::MyFuture<dynamic> f;
+static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
+static field asy::Future<core::List<core::int>> t2 = self::f.then((dynamic _) → dynamic => <dynamic>[3]);
+static method g2() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = <dynamic>[3];
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = asy::Future::value<dynamic>(<dynamic>[3]);
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..c4d07ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
@@ -0,0 +1,75 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value([dynamic x = null]) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static field self::MyFuture<dynamic> f;
+static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.async::FutureOr<dart.core::int>'.
+        new /*@typeArgs=int*/ Future.value('hi'));
+                                           ^"));
+static field asy::Future<core::List<core::int>> t2 = self::f.{self::MyFuture::then}<core::List<core::int>>((dynamic _) → core::List<core::int> => <core::int>[3]);
+static method g2() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = <core::int>[3];
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = asy::Future::value<core::List<core::int>>(<core::int>[3]);
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..793eefb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.direct.transformed.expect
@@ -0,0 +1,72 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value([dynamic x = null]) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static field self::MyFuture<dynamic> f;
+static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
+static field asy::Future<core::List<core::int>> t2 = self::f.then((dynamic _) → dynamic => <dynamic>[3]);
+static method g2() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = <dynamic>[3];
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = new self::MyFuture::value<dynamic>(<dynamic>[3]);
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..d4ffd12
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
@@ -0,0 +1,72 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value([dynamic x = null]) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static field self::MyFuture<dynamic> f;
+static field asy::Future<core::int> t1 = self::f.{self::MyFuture::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
+static field asy::Future<core::List<core::int>> t2 = self::f.{self::MyFuture::then}<core::List<core::int>>((dynamic _) → core::List<core::int> => <core::int>[3]);
+static method g2() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = <core::int>[3];
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = new self::MyFuture::value<core::List<core::int>>(<core::int>[3]);
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
new file mode 100644
index 0000000..9d94cef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.direct.transformed.expect
@@ -0,0 +1,72 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value([dynamic x = null]) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static field asy::Future<dynamic> f;
+static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => asy::Future::value<dynamic>("hi"));
+static field asy::Future<core::List<core::int>> t2 = self::f.then((dynamic _) → dynamic => <dynamic>[3]);
+static method g2() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = <dynamic>[3];
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = asy::Future::value<dynamic>(<dynamic>[3]);
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
new file mode 100644
index 0000000..747af63
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
@@ -0,0 +1,75 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value([dynamic x = null]) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static field asy::Future<dynamic> f;
+static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → asy::Future<core::int> => asy::Future::value<core::int>(let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/future_union_downwards_3.dart:21:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::FutureOr<dart.core::int>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.async::FutureOr<dart.core::int>'.
+        new /*@typeArgs=int*/ Future.value('hi'));
+                                           ^"));
+static field asy::Future<core::List<core::int>> t2 = self::f.{asy::Future::then}<core::List<core::int>>((dynamic _) → core::List<core::int> => <core::int>[3]);
+static method g2() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = <core::int>[3];
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = asy::Future::value<core::List<core::int>>(<core::int>[3]);
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
new file mode 100644
index 0000000..306af4b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.direct.transformed.expect
@@ -0,0 +1,72 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value([dynamic x = null]) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(dynamic invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static field asy::Future<dynamic> f;
+static field asy::Future<core::int> t1 = self::f.then((dynamic _) → dynamic => new self::MyFuture::value<dynamic>("hi"));
+static field asy::Future<core::List<core::int>> t2 = self::f.then((dynamic _) → dynamic => <dynamic>[3]);
+static method g2() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = <dynamic>[3];
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = new self::MyFuture::value<dynamic>(<dynamic>[3]);
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
new file mode 100644
index 0000000..58bf77e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
@@ -0,0 +1,72 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class MyFuture<T extends core::Object> extends core::Object implements asy::Future<self::MyFuture::T> {
+  constructor •() → void
+    : super core::Object::•() {}
+  constructor value([dynamic x = null]) → void
+    : super core::Object::•() {}
+  abstract method noSuchMethod(core::Invocation invocation) → dynamic;
+  method then<S extends core::Object>((self::MyFuture::T) → asy::FutureOr<self::MyFuture::then::S> f, {core::Function onError = null}) → self::MyFuture<self::MyFuture::then::S>
+    return null;
+}
+static field asy::Future<dynamic> f;
+static field asy::Future<core::int> t1 = self::f.{asy::Future::then}<core::int>((dynamic _) → self::MyFuture<core::int> => new self::MyFuture::value<core::int>("hi"));
+static field asy::Future<core::List<core::int>> t2 = self::f.{asy::Future::then}<core::List<core::int>>((dynamic _) → core::List<core::int> => <core::int>[3]);
+static method g2() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = <core::int>[3];
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method g3() → asy::Future<core::List<core::int>> /* originally async */ {
+  final asy::Completer<core::List<core::int>> :completer = asy::Completer::sync<core::List<core::int>>();
+  asy::FutureOr<core::List<core::int>> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L2:
+      {
+        :return_value = new self::MyFuture::value<core::List<core::int>>(<core::int>[3]);
+        break #L2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.direct.transformed.expect
new file mode 100644
index 0000000..4851f62
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.direct.transformed.expect
@@ -0,0 +1,41 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        asy::Future<core::List<self::A>> f1 = null;
+        asy::Future<core::List<self::A>> f2 = null;
+        [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::wait<dynamic>(<dynamic>[f1, f2]), :async_op_then, :async_op_error, :async_op) in null;
+        core::List<core::List<self::A>> merged = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
new file mode 100644
index 0000000..17ee2b4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
@@ -0,0 +1,41 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        asy::Future<core::List<self::A>> f1 = null;
+        asy::Future<core::List<self::A>> f2 = null;
+        [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::wait<core::List<self::A>>(<asy::Future<core::List<self::A>>>[f1, f2]), :async_op_then, :async_op_error, :async_op) in null;
+        core::List<core::List<self::A>> merged = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.direct.transformed.expect
new file mode 100644
index 0000000..826a96d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.direct.transformed.expect
@@ -0,0 +1,37 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method id<T extends core::Object>(self::id::T x) → self::id::T
+  return x;
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        asy::Future<core::String> f;
+        [yield] let dynamic #t1 = asy::_awaitHelper(self::id<dynamic>(f), :async_op_then, :async_op_error, :async_op) in null;
+        core::String s = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
new file mode 100644
index 0000000..0a3ce6b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
@@ -0,0 +1,37 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method id<T extends core::Object>(self::id::T x) → self::id::T
+  return x;
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        asy::Future<core::String> f;
+        [yield] let dynamic #t1 = asy::_awaitHelper(self::id<asy::FutureOr<core::String>>(f), :async_op_then, :async_op_error, :async_op) in null;
+        core::String s = :result;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.direct.transformed.expect
new file mode 100644
index 0000000..0747a44
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.direct.transformed.expect
@@ -0,0 +1,55 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        dynamic b = asy::Future::value<self::B>(new self::B::•());
+        dynamic c = asy::Future::value<self::C>(new self::C::•());
+        dynamic lll = <dynamic>[b, c];
+        [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::wait<dynamic>(lll), :async_op_then, :async_op_error, :async_op) in null;
+        dynamic result = :result;
+        [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::wait<dynamic>(<dynamic>[b, c]), :async_op_then, :async_op_error, :async_op) in null;
+        dynamic result2 = :result;
+        core::List<self::A> list = result;
+        list = result2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
new file mode 100644
index 0000000..6fc7a69
--- /dev/null
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
@@ -0,0 +1,55 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        asy::Future<self::B> b = asy::Future::value<self::B>(new self::B::•());
+        asy::Future<self::C> c = asy::Future::value<self::C>(new self::C::•());
+        core::List<asy::Future<self::A>> lll = <asy::Future<self::A>>[b, c];
+        [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::wait<self::A>(lll), :async_op_then, :async_op_error, :async_op) in null;
+        core::List<self::A> result = :result;
+        [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::wait<self::A>(<asy::Future<self::A>>[b, c]), :async_op_then, :async_op_error, :async_op) in null;
+        core::List<self::A> result2 = :result;
+        core::List<self::A> list = result;
+        list = result2;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generator_closure.dart.direct.transformed.expect
new file mode 100644
index 0000000..8d4c0ac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.direct.transformed.expect
@@ -0,0 +1,45 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method foo(() → asy::Stream<core::int> values) → void {}
+static method main() → void {
+  self::foo(() → asy::Stream<dynamic> /* originally async* */ {
+    asy::_AsyncStarStreamController<dynamic> :controller;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try
+        try {
+          #L1:
+          {
+            if(:controller.{asy::_AsyncStarStreamController::add}(0))
+              return null;
+            else
+              [yield] null;
+            if(:controller.{asy::_AsyncStarStreamController::add}(1))
+              return null;
+            else
+              [yield] null;
+          }
+          return;
+        }
+        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+          :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+        }
+      finally {
+        :controller.{asy::_AsyncStarStreamController::close}();
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+    return :controller.{asy::_AsyncStarStreamController::stream};
+  });
+}
diff --git a/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect
new file mode 100644
index 0000000..11c300e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generator_closure.dart.strong.transformed.expect
@@ -0,0 +1,45 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method foo(() → asy::Stream<core::int> values) → void {}
+static method main() → void {
+  self::foo(() → asy::Stream<core::int> /* originally async* */ {
+    asy::_AsyncStarStreamController<core::int> :controller;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try
+        try {
+          #L1:
+          {
+            if(:controller.{asy::_AsyncStarStreamController::add}(0))
+              return null;
+            else
+              [yield] null;
+            if(:controller.{asy::_AsyncStarStreamController::add}(1))
+              return null;
+            else
+              [yield] null;
+          }
+          return;
+        }
+        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+          :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+        }
+      finally {
+        :controller.{asy::_AsyncStarStreamController::close}();
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :controller = new asy::_AsyncStarStreamController::•<core::int>(:async_op);
+    return :controller.{asy::_AsyncStarStreamController::stream};
+  });
+}
diff --git a/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.direct.transformed.expect
new file mode 100644
index 0000000..e583060
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_functions_return_typedef.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef ToValue<T extends core::Object> = (T) → void;
+static method main() → dynamic {
+  function f<T extends core::Object>(T x) → (T) → void
+    return null;
+  dynamic x = f.call<core::int>(42);
+  dynamic y = f.call(42);
+  (core::int) → void takesInt = x;
+  takesInt = y;
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.direct.transformed.expect
new file mode 100644
index 0000000..a770f08
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f<S extends core::Object, T extends core::Object>(self::f::S s) → self::f::T
+  return null;
+static method main() → dynamic {
+  core::String x = self::f<dynamic, dynamic>(42);
+  core::String y = self::f.call(42);
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..e9fb8da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_basic_downward_inference.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f<S extends core::Object, T extends core::Object>(self::f::S s) → self::f::T
+  return null;
+static method main() → dynamic {
+  core::String x = self::f<core::int, core::String>(42);
+  core::String y = self::f.call<core::int, core::String>(42);
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..4b4f413
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_correctly_recognize_generic_upper_bound.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo<T extends core::Pattern> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method method<U extends self::Foo::T>(self::Foo::method::U u) → self::Foo::method::U
+    return u;
+}
+static method main() → dynamic {
+  new self::Foo::•<core::String>().method(42);
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.direct.transformed.expect
new file mode 100644
index 0000000..7e5ac84
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+
+static method printInt(core::int x) → void
+  return core::print(x);
+static method printDouble(core::double x) → void
+  return core::print(x);
+static method myMax(core::num x, core::num y) → core::num
+  return math::max<dynamic>(x, y);
+static method f() → dynamic {
+  self::printInt(math::max<dynamic>(1, 2));
+  self::printInt(math::min<dynamic>(1, 2));
+  self::printDouble(math::max<dynamic>(1.0, 2.0));
+  self::printDouble(math::min<dynamic>(1.0, 2.0));
+  self::printInt(self::myMax(1, 2));
+  self::printInt(self::myMax(1, 2) as core::int);
+  self::printInt(math::max<dynamic>(1, 2.0));
+  self::printInt(math::min<dynamic>(1, 2.0));
+  self::printDouble(math::max<dynamic>(1, 2.0));
+  self::printDouble(math::min<dynamic>(1, 2.0));
+  self::printInt(math::min<dynamic>("hi", "there"));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect
new file mode 100644
index 0000000..6f7a974
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart.strong.transformed.expect
@@ -0,0 +1,43 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+
+static method printInt(core::int x) → void
+  return core::print(x);
+static method printDouble(core::double x) → void
+  return core::print(x);
+static method myMax(core::num x, core::num y) → core::num
+  return math::max<core::num>(x, y);
+static method f() → dynamic {
+  self::printInt(math::max<core::int>(1, 2));
+  self::printInt(math::min<core::int>(1, 2));
+  self::printDouble(math::max<core::double>(1.0, 2.0));
+  self::printDouble(math::min<core::double>(1.0, 2.0));
+  self::printInt(self::myMax(1, 2) as{TypeError} core::int);
+  self::printInt(self::myMax(1, 2) as core::int);
+  self::printInt(math::max<core::int>(1, let final core::double #t1 = 2.0 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:29:71: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*@typeArgs=int*/ max(1, /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 2.0));
+                                                                      ^"));
+  self::printInt(math::min<core::int>(1, let final core::double #t2 = 2.0 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:31:71: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*@typeArgs=int*/ min(1, /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 2.0));
+                                                                      ^"));
+  self::printDouble(math::max<core::double>(let final core::int #t3 = 1 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:33:71: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::double'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::double'.
+      /*@typeArgs=double*/ max(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 1, 2.0));
+                                                                      ^", 2.0));
+  self::printDouble(math::min<core::double>(let final core::int #t4 = 1 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:35:71: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::double'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::double'.
+      /*@typeArgs=double*/ min(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 1, 2.0));
+                                                                      ^", 2.0));
+  self::printInt(math::min<core::int>(let final core::String #t5 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:39:46: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"hi\",
+                                             ^", let final core::String #t6 = "there" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_dart_math_min_max.dart:40:46: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ \"there\"));
+                                             ^"));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.direct.transformed.expect
new file mode 100644
index 0000000..7e92972
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_do_not_infer_invalid_override_of_generic_method.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(self::C::m::T x) → self::C::m::T
+    return x;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method m(dynamic x) → dynamic
+    return x;
+}
+static method main() → dynamic {
+  core::int y = new self::D::•().m<core::int>(42);
+  core::print(y);
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.direct.transformed.expect
new file mode 100644
index 0000000..e070910
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f<T extends core::Object>(core::List<self::f::T> s) → self::f::T
+  return null;
+static method test() → dynamic {
+  core::String x = self::f<dynamic>(<dynamic>["hi"]);
+  core::String y = self::f<dynamic>(<dynamic>[42]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect
new file mode 100644
index 0000000..4b349ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f<T extends core::Object>(core::List<self::f::T> s) → self::f::T
+  return null;
+static method test() → dynamic {
+  core::String x = self::f<core::String>(<core::String>["hi"]);
+  core::String y = self::f<core::String>(<core::String>[let final core::int #t1 = 42 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_downwards_inference_affects_arguments.dart:13:76: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+          /*@typeArgs=String*/ [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/ 42]);
+                                                                           ^"]);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.direct.transformed.expect
new file mode 100644
index 0000000..f4c3fe5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::List<core::int> o;
+  core::int y = o.fold(0, (dynamic x, dynamic y) → dynamic => x.+(y));
+  dynamic z = o.fold(0, (dynamic x, dynamic y) → dynamic => x.+(y));
+  y = z;
+}
+static method functionExpressionInvocation() → void {
+  core::List<core::int> o;
+  core::int y = o.fold.call(0, (dynamic x, dynamic y) → dynamic => x.+(y));
+  dynamic z = o.fold.call(0, (dynamic x, dynamic y) → dynamic => x.+(y));
+  y = z;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.strong.transformed.expect
new file mode 100644
index 0000000..5ac4800
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_downwards_inference_fold.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::List<core::int> o;
+  core::int y = o.{core::Iterable::fold}<core::int>(0, (core::int x, core::int y) → core::int => x.{core::num::+}(y));
+  dynamic z = o.{core::Iterable::fold}<dynamic>(0, (dynamic x, core::int y) → dynamic => x.+(y));
+  y = z as{TypeError} core::int;
+}
+static method functionExpressionInvocation() → void {
+  core::List<core::int> o;
+  core::int y = o.{core::Iterable::fold}.call<core::int>(0, (core::int x, core::int y) → core::int => x.{core::num::+}(y));
+  dynamic z = o.{core::Iterable::fold}.call<dynamic>(0, (dynamic x, core::int y) → dynamic => x.+(y));
+  y = z as{TypeError} core::int;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.direct.transformed.expect
new file mode 100644
index 0000000..af643ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_handle_override_of_non_generic_with_generic.dart.direct.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m(dynamic x) → dynamic
+    return x;
+  method g(core::int x) → dynamic
+    return x;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method m<T extends core::Object>(self::D::m::T x) → self::D::m::T
+    return x;
+  method g<T extends core::Object>(self::D::g::T x) → self::D::g::T
+    return x;
+}
+static method main() → dynamic {
+  core::int y = (new self::D::•() as self::C).m(42);
+  core::print(y);
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..99e84b5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<V extends core::Object> = (V) → void;
+class C<T extends core::Object> extends self::D<self::C::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method f<U extends core::Object>(dynamic x) → dynamic {}
+}
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends core::Object>(self::D::f::U u) → (self::D::f::U) → void
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..b141cc6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<V extends core::Object> = (V) → void;
+class C<T extends core::Object> extends self::D<self::C::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method f<U extends core::Object>(self::C::f::U x) → (self::C::f::U) → void {}
+}
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends core::Object>(self::D::f::U u) → (self::D::f::U) → void
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.direct.transformed.expect
new file mode 100644
index 0000000..551a22b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef G<V extends core::Object> = () → core::List<V>;
+class C<T extends core::Object> extends self::D<self::C::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method f<U extends core::Object>(dynamic g) → dynamic
+    return null;
+}
+abstract class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f<U extends core::Object>(() → core::List<self::D::f::U> g) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.transformed.expect
new file mode 100644
index 0000000..4e1632a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_parameter_type2.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef G<V extends core::Object> = () → core::List<V>;
+class C<T extends core::Object> extends self::D<self::C::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method f<U extends core::Object>(() → core::List<self::C::f::U> g) → void
+    return null;
+}
+abstract class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f<U extends core::Object>(() → core::List<self::D::f::U> g) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..4465b65
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<V extends core::Object> = () → V;
+class C<T extends core::Object> extends self::D<self::C::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method f<U extends core::Object>(dynamic x) → dynamic {}
+}
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends core::Object>(self::D::f::U u) → () → self::D::f::U
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..eb9055b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_function_return_type.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<V extends core::Object> = () → V;
+class C<T extends core::Object> extends self::D<self::C::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method f<U extends core::Object>(self::C::f::U x) → () → self::C::f::U {}
+}
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends core::Object>(self::D::f::U u) → () → self::D::f::U
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.direct.transformed.expect
new file mode 100644
index 0000000..3a68a44
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.direct.transformed.expect
@@ -0,0 +1,71 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::num>(self::C::m::T x, self::C::m::T y) → self::C::m::T
+    return null;
+}
+static method test() → dynamic {
+  self::takeIII(math::max);
+  self::takeDDD(math::max);
+  self::takeNNN(math::max);
+  self::takeIDN(math::max);
+  self::takeDIN(math::max);
+  self::takeIIN(math::max);
+  self::takeDDN(math::max);
+  self::takeIIO(math::max);
+  self::takeDDO(math::max);
+  self::takeOOI(math::max);
+  self::takeIDI(math::max);
+  self::takeDID(math::max);
+  self::takeOON(math::max);
+  self::takeOOO(math::max);
+  self::takeIII(math::min);
+  self::takeDDD(math::min);
+  self::takeNNN(math::min);
+  self::takeIDN(math::min);
+  self::takeDIN(math::min);
+  self::takeIIN(math::min);
+  self::takeDDN(math::min);
+  self::takeIIO(math::min);
+  self::takeDDO(math::min);
+  self::takeOOI(math::min);
+  self::takeIDI(math::min);
+  self::takeDID(math::min);
+  self::takeOON(math::min);
+  self::takeOOO(math::min);
+  self::takeIII(new self::C::•().m);
+  self::takeDDD(new self::C::•().m);
+  self::takeNNN(new self::C::•().m);
+  self::takeIDN(new self::C::•().m);
+  self::takeDIN(new self::C::•().m);
+  self::takeIIN(new self::C::•().m);
+  self::takeDDN(new self::C::•().m);
+  self::takeIIO(new self::C::•().m);
+  self::takeDDO(new self::C::•().m);
+  self::takeOON(new self::C::•().m);
+  self::takeOOO(new self::C::•().m);
+  self::takeOOI(new self::C::•().m);
+  self::takeIDI(new self::C::•().m);
+  self::takeDID(new self::C::•().m);
+}
+static method takeIII((core::int, core::int) → core::int fn) → void {}
+static method takeDDD((core::double, core::double) → core::double fn) → void {}
+static method takeIDI((core::double, core::int) → core::int fn) → void {}
+static method takeDID((core::int, core::double) → core::double fn) → void {}
+static method takeIDN((core::double, core::int) → core::num fn) → void {}
+static method takeDIN((core::int, core::double) → core::num fn) → void {}
+static method takeIIN((core::int, core::int) → core::num fn) → void {}
+static method takeDDN((core::double, core::double) → core::num fn) → void {}
+static method takeNNN((core::num, core::num) → core::num fn) → void {}
+static method takeOON((core::Object, core::Object) → core::num fn) → void {}
+static method takeOOO((core::Object, core::Object) → core::num fn) → void {}
+static method takeOOI((core::Object, core::Object) → core::int fn) → void {}
+static method takeIIO((core::int, core::int) → core::Object fn) → void {}
+static method takeDDO((core::double, core::double) → core::Object fn) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
new file mode 100644
index 0000000..676fa226
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart.strong.transformed.expect
@@ -0,0 +1,89 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::num>(self::C::m::T x, self::C::m::T y) → self::C::m::T
+    return null;
+}
+static method test() → dynamic {
+  self::takeIII(math::max<core::int>);
+  self::takeDDD(math::max<core::double>);
+  self::takeNNN(math::max<core::num>);
+  self::takeIDN(math::max<core::num>);
+  self::takeDIN(math::max<core::num>);
+  self::takeIIN(math::max<core::int>);
+  self::takeDDN(math::max<core::double>);
+  self::takeIIO(math::max<core::int>);
+  self::takeDDO(math::max<core::double>);
+  self::takeOOI((math::max<core::Object>) as{TypeError} (core::Object, core::Object) → core::int);
+  self::takeIDI(let final (core::num, core::num) → core::num #t1 = math::max<core::num> in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:28:73: Error: A value of type '(dart.core::num, dart.core::num) \u8594 dart.core::num' can't be assigned to a variable of type '(dart.core::double, dart.core::int) \u8594 dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.core::double, dart.core::int) \u8594 dart.core::int'.
+      /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
+                                                                        ^");
+  self::takeDID(let final (core::num, core::num) → core::num #t2 = math::max<core::num> in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:30:73: Error: A value of type '(dart.core::num, dart.core::num) \u8594 dart.core::num' can't be assigned to a variable of type '(dart.core::int, dart.core::double) \u8594 dart.core::double'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.core::int, dart.core::double) \u8594 dart.core::double'.
+      /*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ math.max);
+                                                                        ^");
+  self::takeOON((math::max<core::Object>) as{TypeError} (core::Object, core::Object) → core::num);
+  self::takeOOO((math::max<core::Object>) as{TypeError} (core::Object, core::Object) → core::num);
+  self::takeIII(math::min<core::int>);
+  self::takeDDD(math::min<core::double>);
+  self::takeNNN(math::min<core::num>);
+  self::takeIDN(math::min<core::num>);
+  self::takeDIN(math::min<core::num>);
+  self::takeIIN(math::min<core::int>);
+  self::takeDDN(math::min<core::double>);
+  self::takeIIO(math::min<core::int>);
+  self::takeDDO(math::min<core::double>);
+  self::takeOOI((math::min<core::Object>) as{TypeError} (core::Object, core::Object) → core::int);
+  self::takeIDI(let final (core::num, core::num) → core::num #t3 = math::min<core::num> in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:46:72: Error: A value of type '(dart.core::num, dart.core::num) \u8594 dart.core::num' can't be assigned to a variable of type '(dart.core::double, dart.core::int) \u8594 dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.core::double, dart.core::int) \u8594 dart.core::int'.
+  takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
+                                                                       ^");
+  self::takeDID(let final (core::num, core::num) → core::num #t4 = math::min<core::num> in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:47:72: Error: A value of type '(dart.core::num, dart.core::num) \u8594 dart.core::num' can't be assigned to a variable of type '(dart.core::int, dart.core::double) \u8594 dart.core::double'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.core::int, dart.core::double) \u8594 dart.core::double'.
+  takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ min);
+                                                                       ^");
+  self::takeOON((math::min<core::Object>) as{TypeError} (core::Object, core::Object) → core::num);
+  self::takeOOO((math::min<core::Object>) as{TypeError} (core::Object, core::Object) → core::num);
+  self::takeIII(new self::C::•().{self::C::m}<core::int>);
+  self::takeDDD(new self::C::•().{self::C::m}<core::double>);
+  self::takeNNN(new self::C::•().{self::C::m}<core::num>);
+  self::takeIDN(new self::C::•().{self::C::m}<core::num>);
+  self::takeDIN(new self::C::•().{self::C::m}<core::num>);
+  self::takeIIN(new self::C::•().{self::C::m}<core::int>);
+  self::takeDDN(new self::C::•().{self::C::m}<core::double>);
+  self::takeIIO(new self::C::•().{self::C::m}<core::int>);
+  self::takeDDO(new self::C::•().{self::C::m}<core::double>);
+  self::takeOON((new self::C::•().{self::C::m}<core::Object>) as{TypeError} (core::Object, core::Object) → core::num);
+  self::takeOOO((new self::C::•().{self::C::m}<core::Object>) as{TypeError} (core::Object, core::Object) → core::num);
+  self::takeOOI((new self::C::•().{self::C::m}<core::Object>) as{TypeError} (core::Object, core::Object) → core::int);
+  self::takeIDI(let final (core::num, core::num) → core::num #t5 = new self::C::•().{self::C::m}<core::num> in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:86:30: Error: A value of type '(dart.core::num, dart.core::num) \u8594 dart.core::num' can't be assigned to a variable of type '(dart.core::double, dart.core::int) \u8594 dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.core::double, dart.core::int) \u8594 dart.core::int'.
+          . /*@target=C::m*/ m);
+                             ^");
+  self::takeDID(let final (core::num, core::num) → core::num #t6 = new self::C::•().{self::C::m}<core::num> in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_infer_generic_instantiation.dart:89:30: Error: A value of type '(dart.core::num, dart.core::num) \u8594 dart.core::num' can't be assigned to a variable of type '(dart.core::int, dart.core::double) \u8594 dart.core::double'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.core::int, dart.core::double) \u8594 dart.core::double'.
+          . /*@target=C::m*/ m);
+                             ^");
+}
+static method takeIII((core::int, core::int) → core::int fn) → void {}
+static method takeDDD((core::double, core::double) → core::double fn) → void {}
+static method takeIDI((core::double, core::int) → core::int fn) → void {}
+static method takeDID((core::int, core::double) → core::double fn) → void {}
+static method takeIDN((core::double, core::int) → core::num fn) → void {}
+static method takeDIN((core::int, core::double) → core::num fn) → void {}
+static method takeIIN((core::int, core::int) → core::num fn) → void {}
+static method takeDDN((core::double, core::double) → core::num fn) → void {}
+static method takeNNN((core::num, core::num) → core::num fn) → void {}
+static method takeOON((core::Object, core::Object) → core::num fn) → void {}
+static method takeOOO((core::Object, core::Object) → core::num fn) → void {}
+static method takeOOI((core::Object, core::Object) → core::int fn) → void {}
+static method takeIIO((core::int, core::int) → core::Object fn) → void {}
+static method takeDDO((core::double, core::double) → core::Object fn) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..41749ee
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(self::C::m::T x) → self::C::m::T
+    return x;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method m<S extends core::Object>(dynamic x) → dynamic
+    return x;
+}
+static method main() → dynamic {
+  core::int y = new self::D::•().m<core::int>(42);
+  core::print(y);
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..671ce41
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_infer_generic_method_type.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(self::C::m::T x) → self::C::m::T
+    return x;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method m<S extends core::Object>(self::D::m::S x) → self::D::m::S
+    return x;
+}
+static method main() → dynamic {
+  core::int y = new self::D::•().{self::D::m}<core::int>(42);
+  core::print(y);
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.direct.transformed.expect
new file mode 100644
index 0000000..c884e38
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f() → void {
+  core::List<core::String> y;
+  core::Iterable<core::String> x = y.map((core::String z) → dynamic => 1.0);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect
new file mode 100644
index 0000000..9d59ac7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_inference_error.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f() → void {
+  core::List<core::String> y;
+  core::Iterable<core::String> x = y.{core::Iterable::map}<core::String>((core::String z) → core::String => let final core::double #t1 = 1.0 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_inference_error.dart:13:11: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+          1.0);
+          ^");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.direct.transformed.expect
new file mode 100644
index 0000000..cda283f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method make(core::int x) → asy::Future<core::int>
+  return asy::Future::•<dynamic>(() → dynamic => x);
+static method test() → dynamic {
+  core::Iterable<asy::Future<core::int>> list = <core::int>[1, 2, 3].map(self::make);
+  asy::Future<core::List<core::int>> results = asy::Future::wait<dynamic>(list);
+  asy::Future<core::String> results2 = results.then((core::List<core::int> list) → dynamic => list.fold("", (dynamic x, dynamic y) → dynamic => x.+(y.toString())));
+  asy::Future<core::String> results3 = results.then((core::List<core::int> list) → dynamic => list.fold("", (core::String x, dynamic y) → dynamic => x.+(y.toString())));
+  asy::Future<core::String> results4 = results.then((core::List<core::int> list) → dynamic => list.fold<core::String>("", (dynamic x, dynamic y) → dynamic => x.+(y.toString())));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
new file mode 100644
index 0000000..fd713bd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method make(core::int x) → asy::Future<core::int>
+  return asy::Future::•<core::int>(() → core::int => x);
+static method test() → dynamic {
+  core::Iterable<asy::Future<core::int>> list = <core::int>[1, 2, 3].{core::Iterable::map}<asy::Future<core::int>>(self::make);
+  asy::Future<core::List<core::int>> results = asy::Future::wait<core::int>(list);
+  asy::Future<core::String> results2 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → asy::FutureOr<core::String> => list.{core::Iterable::fold}<asy::FutureOr<core::String>>("", (asy::FutureOr<core::String> x, core::int y) → asy::FutureOr<core::String> => (let final asy::FutureOr<core::String> #t1 = x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:23:120: Error: The method '+' isn't defined for the class 'dart.async::FutureOr<dart.core::String>'.
+Try correcting the name to the name of an existing method, or defining a method named '+'.
+                          /*@type=int*/ y) => /*info:DYNAMIC_CAST,info:DYNAMIC_INVOKE*/ x /*error:UNDEFINED_OPERATOR*/ +
+                                                                                                                       ^") as{TypeError} asy::FutureOr<core::String>));
+  asy::Future<core::String> results3 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → asy::FutureOr<core::String> => list.{core::Iterable::fold}<asy::FutureOr<core::String>>("", let final (core::String, core::int) → core::String #t2 = (core::String x, core::int y) → core::String => x.{core::String::+}(y.{core::int::toString}()) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/generic_methods_iterable_and_future.dart:31:108: Error: A value of type '(dart.core::String, dart.core::int) \u8594 dart.core::String' can't be assigned to a variable of type '(dart.async::FutureOr<dart.core::String>, dart.core::int) \u8594 dart.async::FutureOr<dart.core::String>'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.async::FutureOr<dart.core::String>, dart.core::int) \u8594 dart.async::FutureOr<dart.core::String>'.
+                  /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ /*@returnType=String*/ (String
+                                                                                                           ^"));
+  asy::Future<core::String> results4 = results.{asy::Future::then}<core::String>((core::List<core::int> list) → core::String => list.{core::Iterable::fold}<core::String>("", (core::String x, core::int y) → core::String => x.{core::String::+}(y.{core::int::toString}())));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.direct.transformed.expect
new file mode 100644
index 0000000..24b82f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+
+class Trace extends core::Object {
+  field core::List<self::Frame> frames = <dynamic>[];
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Frame extends core::Object {
+  field core::String location = "";
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::List<self::Trace> traces = <dynamic>[];
+  dynamic longest = traces.map((dynamic trace) → dynamic {
+    return trace.frames.map((dynamic frame) → dynamic => frame.location.length).fold(0, math::max);
+  }).fold(0, math::max);
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.transformed.expect
new file mode 100644
index 0000000..1c5bf35
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_nested_generic_instantiation.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:math" as math;
+
+class Trace extends core::Object {
+  field core::List<self::Frame> frames = <self::Frame>[];
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Frame extends core::Object {
+  field core::String location = "";
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::List<self::Trace> traces = <self::Trace>[];
+  core::int longest = traces.{core::Iterable::map}<core::int>((self::Trace trace) → core::int {
+    return trace.{self::Trace::frames}.{core::Iterable::map}<core::int>((self::Frame frame) → core::int => frame.{self::Frame::location}.{core::String::length}).{core::Iterable::fold}<core::int>(0, math::max<core::int>);
+  }).{core::Iterable::fold}<core::int>(0, math::max<core::int>);
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..1c4540d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = (core::int) → core::Iterable<core::num>;
+typedef G = (core::double) → core::List<core::int>;
+static method generic<T extends core::Object>((self::generic::T) → dynamic a, (self::generic::T) → dynamic b) → self::generic::T
+  return null;
+static method main() → dynamic {
+  dynamic v = self::generic<dynamic>(((core::int) → core::Iterable<core::num> f) → dynamic => null, ((core::double) → core::List<core::int> g) → dynamic => null);
+}
diff --git a/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..0aafd64
--- /dev/null
+++ b/pkg/front_end/testcases/inference/generic_methods_uses_greatest_lower_bound.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = (core::int) → core::Iterable<core::num>;
+typedef G = (core::double) → core::List<core::int>;
+static method generic<T extends core::Object>((self::generic::T) → dynamic a, (self::generic::T) → dynamic b) → self::generic::T
+  return null;
+static method main() → dynamic {
+  (core::num) → core::List<core::int> v = self::generic<(core::num) → core::List<core::int>>(((core::int) → core::Iterable<core::num> f) → core::Null => null, ((core::double) → core::List<core::int> g) → core::Null => null);
+}
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.direct.transformed.expect
new file mode 100644
index 0000000..e98bebc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class C<E extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method sort([(self::C::E, self::C::E) → core::int compare = null]) → void {
+    self::C::sort2<dynamic>(this, let final dynamic #t1 = compare in #t1.==(null) ? self::C::_compareAny : #t1);
+  }
+  static method _compareAny(dynamic a, dynamic b) → core::int {
+    throw "unimplemented";
+  }
+  static method sort2<E extends core::Object>(self::C<self::C::sort2::E> a, (self::C::sort2::E, self::C::sort2::E) → core::int compare) → void {
+    throw "unimplemented";
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.transformed.expect
new file mode 100644
index 0000000..949aa38
--- /dev/null
+++ b/pkg/front_end/testcases/inference/greatest_closure_multiple_params.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class C<E extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method sort([(self::C::E, self::C::E) → core::int compare = null]) → void {
+    self::C::sort2<self::C::E>(this, let final (self::C::E, self::C::E) → core::int #t1 = compare in #t1.==(null) ?{(self::C::E, self::C::E) → core::int} self::C::_compareAny : #t1);
+  }
+  static method _compareAny(dynamic a, dynamic b) → core::int {
+    throw "unimplemented";
+  }
+  static method sort2<E extends core::Object>(self::C<self::C::sort2::E> a, (self::C::sort2::E, self::C::sort2::E) → core::int compare) → void {
+    throw "unimplemented";
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..a69e1d2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(dynamic index, dynamic value) → dynamic {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(dynamic index, dynamic value) → void {}
+}
+class D extends self::C implements self::I {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  operator []=(dynamic index, dynamic value) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..bc47488
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(dynamic index, dynamic value) → dynamic {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(dynamic index, dynamic value) → void {}
+}
+class D extends self::C implements self::I {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  operator []=(dynamic index, dynamic value) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..1394b9b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(core::int index, dynamic value) → dynamic {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(core::int index, dynamic value) → void {}
+}
+class D extends self::C implements self::I {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  operator []=(core::int index, dynamic value) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..d1c866b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/index_assign_operator_return_type_2.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(core::int index, dynamic value) → dynamic {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(core::int index, dynamic value) → void {}
+}
+class D extends self::C implements self::I {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  operator []=(core::int index, dynamic value) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..0b3aca2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → dynamic
+    return self::f();
+  set x(dynamic value) → void {}
+}
+class B extends core::Object {
+  field dynamic x = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method f() → dynamic
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..adb834a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_accessor_from_later_inferred_field.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return self::f() as{TypeError} core::int;
+  set x(core::int value) → void {}
+}
+class B extends core::Object {
+  field core::int x = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method f() → dynamic
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.direct.transformed.expect
new file mode 100644
index 0000000..2b083f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.direct.transformed.expect
@@ -0,0 +1,51 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    this.{self::Test::member} = self::f<dynamic>();
+    this.{self::Test::member}.==(null) ? this.{self::Test::member} = self::f<dynamic>() : null;
+    this.{self::Test::member} = this.{self::Test::member}.+(self::f<dynamic>());
+    this.{self::Test::member} = this.{self::Test::member}.*(self::f<dynamic>());
+    this.{self::Test::member} = this.{self::Test::member}.&(self::f<dynamic>());
+    this.{self::Test::member} = this.{self::Test::member}.-(1);
+    this.{self::Test::member} = this.{self::Test::member}.-(1);
+    dynamic v1 = this.{self::Test::member} = self::f<dynamic>();
+    dynamic v2 = let final dynamic #t1 = this.{self::Test::member} in #t1.==(null) ? this.{self::Test::member} = self::f<dynamic>() : #t1;
+    dynamic v4 = this.{self::Test::member} = this.{self::Test::member}.*(self::f<dynamic>());
+    dynamic v5 = this.{self::Test::member} = this.{self::Test::member}.&(self::f<dynamic>());
+    dynamic v6 = this.{self::Test::member} = this.{self::Test::member}.-(1);
+    dynamic v7 = let final dynamic #t2 = this.{self::Test::member} in let final dynamic #t3 = this.{self::Test::member} = #t2.-(1) in #t2;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.transformed.expect
new file mode 100644
index 0000000..9efe1fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this.dart.strong.transformed.expect
@@ -0,0 +1,51 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    this.{self::Test::member} = self::f<self::B>();
+    this.{self::Test::member}.{core::Object::==}(null) ?{self::B} this.{self::Test::member} = self::f<self::B>() : null;
+    this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
+    this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
+    self::B v1 = this.{self::Test::member} = self::f<self::B>();
+    self::B v2 = let final self::B #t1 = this.{self::Test::member} in #t1.{core::Object::==}(null) ?{self::B} this.{self::Test::member} = self::f<self::B>() : #t1;
+    self::B v4 = this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    self::C v5 = this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    self::B v6 = this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
+    self::B v7 = let final self::B #t2 = this.{self::Test::member} in let final self::B #t3 = this.{self::Test::member} = #t2.{self::B::-}(1) in #t2;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..8a46541
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.direct.transformed.expect
@@ -0,0 +1,58 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    dynamic v1 = this.{self::Test1::t} = self::getInt();
+    dynamic v4 = let final dynamic #t1 = this.{self::Test1::t} in #t1.==(null) ? this.{self::Test1::t} = self::getInt() : #t1;
+    dynamic v7 = this.{self::Test1::t} = this.{self::Test1::t}.+(self::getInt());
+    dynamic v10 = this.{self::Test1::t} = this.{self::Test1::t}.+(1);
+    dynamic v11 = let final dynamic #t2 = this.{self::Test1::t} in let final dynamic #t3 = this.{self::Test1::t} = #t2.+(1) in #t2;
+  }
+}
+class Test2 extends core::Object {
+  field core::num t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    dynamic v1 = this.{self::Test2::t} = self::getInt();
+    dynamic v2 = this.{self::Test2::t} = self::getNum();
+    dynamic v3 = this.{self::Test2::t} = self::getDouble();
+    dynamic v4 = let final dynamic #t4 = this.{self::Test2::t} in #t4.==(null) ? this.{self::Test2::t} = self::getInt() : #t4;
+    dynamic v5 = let final dynamic #t5 = this.{self::Test2::t} in #t5.==(null) ? this.{self::Test2::t} = self::getNum() : #t5;
+    dynamic v6 = let final dynamic #t6 = this.{self::Test2::t} in #t6.==(null) ? this.{self::Test2::t} = self::getDouble() : #t6;
+    dynamic v7 = this.{self::Test2::t} = this.{self::Test2::t}.+(self::getInt());
+    dynamic v8 = this.{self::Test2::t} = this.{self::Test2::t}.+(self::getNum());
+    dynamic v9 = this.{self::Test2::t} = this.{self::Test2::t}.+(self::getDouble());
+    dynamic v10 = this.{self::Test2::t} = this.{self::Test2::t}.+(1);
+    dynamic v11 = let final dynamic #t7 = this.{self::Test2::t} in let final dynamic #t8 = this.{self::Test2::t} = #t7.+(1) in #t7;
+  }
+}
+class Test3 extends core::Object {
+  field core::double t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test3() → void {
+    dynamic v3 = this.{self::Test3::t} = self::getDouble();
+    dynamic v6 = let final dynamic #t9 = this.{self::Test3::t} in #t9.==(null) ? this.{self::Test3::t} = self::getDouble() : #t9;
+    dynamic v7 = this.{self::Test3::t} = this.{self::Test3::t}.+(self::getInt());
+    dynamic v8 = this.{self::Test3::t} = this.{self::Test3::t}.+(self::getNum());
+    dynamic v9 = this.{self::Test3::t} = this.{self::Test3::t}.+(self::getDouble());
+    dynamic v10 = this.{self::Test3::t} = this.{self::Test3::t}.+(1);
+    dynamic v11 = let final dynamic #t10 = this.{self::Test3::t} in let final dynamic #t11 = this.{self::Test3::t} = #t10.+(1) in #t10;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..dd244e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_implicit_this_upwards.dart.strong.transformed.expect
@@ -0,0 +1,58 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    core::int v1 = this.{self::Test1::t} = self::getInt();
+    core::int v4 = let final core::int #t1 = this.{self::Test1::t} in #t1.{core::num::==}(null) ?{core::int} this.{self::Test1::t} = self::getInt() : #t1;
+    core::int v7 = this.{self::Test1::t} = this.{self::Test1::t}.{core::num::+}(self::getInt());
+    core::int v10 = this.{self::Test1::t} = this.{self::Test1::t}.{core::num::+}(1);
+    core::int v11 = let final core::int #t2 = this.{self::Test1::t} in let final core::int #t3 = this.{self::Test1::t} = #t2.{core::num::+}(1) in #t2;
+  }
+}
+class Test2 extends core::Object {
+  field core::num t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    core::int v1 = this.{self::Test2::t} = self::getInt();
+    core::num v2 = this.{self::Test2::t} = self::getNum();
+    core::double v3 = this.{self::Test2::t} = self::getDouble();
+    core::num v4 = let final core::num #t4 = this.{self::Test2::t} in #t4.{core::num::==}(null) ?{core::num} this.{self::Test2::t} = self::getInt() : #t4;
+    core::num v5 = let final core::num #t5 = this.{self::Test2::t} in #t5.{core::num::==}(null) ?{core::num} this.{self::Test2::t} = self::getNum() : #t5;
+    core::num v6 = let final core::num #t6 = this.{self::Test2::t} in #t6.{core::num::==}(null) ?{core::num} this.{self::Test2::t} = self::getDouble() : #t6;
+    core::num v7 = this.{self::Test2::t} = this.{self::Test2::t}.{core::num::+}(self::getInt());
+    core::num v8 = this.{self::Test2::t} = this.{self::Test2::t}.{core::num::+}(self::getNum());
+    core::num v9 = this.{self::Test2::t} = this.{self::Test2::t}.{core::num::+}(self::getDouble());
+    core::num v10 = this.{self::Test2::t} = this.{self::Test2::t}.{core::num::+}(1);
+    core::num v11 = let final core::num #t7 = this.{self::Test2::t} in let final core::num #t8 = this.{self::Test2::t} = #t7.{core::num::+}(1) in #t7;
+  }
+}
+class Test3 extends core::Object {
+  field core::double t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test3() → void {
+    core::double v3 = this.{self::Test3::t} = self::getDouble();
+    core::double v6 = let final core::double #t9 = this.{self::Test3::t} in #t9.{core::num::==}(null) ?{core::double} this.{self::Test3::t} = self::getDouble() : #t9;
+    core::double v7 = this.{self::Test3::t} = this.{self::Test3::t}.{core::double::+}(self::getInt());
+    core::double v8 = this.{self::Test3::t} = this.{self::Test3::t}.{core::double::+}(self::getNum());
+    core::double v9 = this.{self::Test3::t} = this.{self::Test3::t}.{core::double::+}(self::getDouble());
+    core::double v10 = this.{self::Test3::t} = this.{self::Test3::t}.{core::double::+}(1);
+    core::double v11 = let final core::double #t10 = this.{self::Test3::t} in let final core::double #t11 = this.{self::Test3::t} = #t10.{core::double::+}(1) in #t10;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.direct.transformed.expect
new file mode 100644
index 0000000..38a2aec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.direct.transformed.expect
@@ -0,0 +1,59 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+  method test() → void {
+    self::Test t = self::f<dynamic>();
+    t.[]=(self::f<dynamic>(), self::f<dynamic>());
+    let final dynamic #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.[](#t2).==(null) ? let final dynamic #t3 = self::f<dynamic>() in let final dynamic #t4 = #t1.[]=(#t2, #t3) in #t3 : null;
+    let final dynamic #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.[]=(#t6, #t5.[](#t6).+(self::f<dynamic>()));
+    let final dynamic #t7 = t in let final dynamic #t8 = self::f<dynamic>() in #t7.[]=(#t8, #t7.[](#t8).*(self::f<dynamic>()));
+    let final dynamic #t9 = t in let final dynamic #t10 = self::f<dynamic>() in #t9.[]=(#t10, #t9.[](#t10).&(self::f<dynamic>()));
+    let final dynamic #t11 = t in let final dynamic #t12 = self::f<dynamic>() in let final dynamic #t13 = #t11.[](#t12).-(1) in let final dynamic #t14 = #t11.[]=(#t12, #t13) in #t13;
+    let final dynamic #t15 = t in let final dynamic #t16 = self::f<dynamic>() in #t15.[]=(#t16, #t15.[](#t16).-(1));
+    dynamic v1 = let final dynamic #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final dynamic #t19 = self::f<dynamic>() in let final dynamic #t20 = #t17.[]=(#t18, #t19) in #t19;
+    dynamic v2 = let final dynamic #t21 = t in let final dynamic #t22 = self::f<dynamic>() in let final dynamic #t23 = #t21.[](#t22) in #t23.==(null) ? let final dynamic #t24 = self::f<dynamic>() in let final dynamic #t25 = #t21.[]=(#t22, #t24) in #t24 : #t23;
+    dynamic v4 = let final dynamic #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final dynamic #t28 = #t26.[](#t27).*(self::f<dynamic>()) in let final dynamic #t29 = #t26.[]=(#t27, #t28) in #t28;
+    dynamic v5 = let final dynamic #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final dynamic #t32 = #t30.[](#t31).&(self::f<dynamic>()) in let final dynamic #t33 = #t30.[]=(#t31, #t32) in #t32;
+    dynamic v6 = let final dynamic #t34 = t in let final dynamic #t35 = self::f<dynamic>() in let final dynamic #t36 = #t34.[](#t35).-(1) in let final dynamic #t37 = #t34.[]=(#t35, #t36) in #t36;
+    dynamic v7 = let final dynamic #t38 = t in let final dynamic #t39 = self::f<dynamic>() in let final dynamic #t40 = #t38.[](#t39) in let final dynamic #t41 = #t38.[]=(#t39, #t40.-(1)) in #t40;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.transformed.expect
new file mode 100644
index 0000000..5675288
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_full.dart.strong.transformed.expect
@@ -0,0 +1,59 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+  method test() → void {
+    self::Test t = self::f<self::Test>();
+    t.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index, self::f<self::B>());
+    let final self::Test #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.{self::Test::[]}(#t2 as{TypeError} self::Index).{core::Object::==}(null) ?{self::B} let final self::B #t3 = self::f<self::B>() in let final void #t4 = #t1.{self::Test::[]=}(#t2 as{TypeError} self::Index, #t3) in #t3 : null;
+    let final self::Test #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.{self::Test::[]=}(#t6 as{TypeError} self::Index, #t5.{self::Test::[]}(#t6 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B);
+    let final self::Test #t7 = t in let final dynamic #t8 = self::f<dynamic>() in #t7.{self::Test::[]=}(#t8 as{TypeError} self::Index, #t7.{self::Test::[]}(#t8 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B));
+    let final self::Test #t9 = t in let final dynamic #t10 = self::f<dynamic>() in #t9.{self::Test::[]=}(#t10 as{TypeError} self::Index, #t9.{self::Test::[]}(#t10 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A));
+    let final self::Test #t11 = t in let final dynamic #t12 = self::f<dynamic>() in let final self::B #t13 = #t11.{self::Test::[]}(#t12 as{TypeError} self::Index).{self::B::-}(1) in let final void #t14 = #t11.{self::Test::[]=}(#t12 as{TypeError} self::Index, #t13) in #t13;
+    let final self::Test #t15 = t in let final dynamic #t16 = self::f<dynamic>() in #t15.{self::Test::[]=}(#t16 as{TypeError} self::Index, #t15.{self::Test::[]}(#t16 as{TypeError} self::Index).{self::B::-}(1));
+    self::B v1 = let final self::Test #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final self::B #t19 = self::f<self::B>() in let final void #t20 = #t17.{self::Test::[]=}(#t18 as{TypeError} self::Index, #t19) in #t19;
+    self::B v2 = let final self::Test #t21 = t in let final dynamic #t22 = self::f<dynamic>() in let final self::B #t23 = #t21.{self::Test::[]}(#t22 as{TypeError} self::Index) in #t23.{core::Object::==}(null) ?{self::B} let final self::B #t24 = self::f<self::B>() in let final void #t25 = #t21.{self::Test::[]=}(#t22 as{TypeError} self::Index, #t24) in #t24 : #t23;
+    self::B v4 = let final self::Test #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final self::B #t28 = #t26.{self::Test::[]}(#t27 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B) in let final void #t29 = #t26.{self::Test::[]=}(#t27 as{TypeError} self::Index, #t28) in #t28;
+    self::C v5 = let final self::Test #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final self::C #t32 = #t30.{self::Test::[]}(#t31 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A) in let final void #t33 = #t30.{self::Test::[]=}(#t31 as{TypeError} self::Index, #t32) in #t32;
+    self::B v6 = let final self::Test #t34 = t in let final dynamic #t35 = self::f<dynamic>() in let final self::B #t36 = #t34.{self::Test::[]}(#t35 as{TypeError} self::Index).{self::B::-}(1) in let final void #t37 = #t34.{self::Test::[]=}(#t35 as{TypeError} self::Index, #t36) in #t36;
+    self::B v7 = let final self::Test #t38 = t in let final dynamic #t39 = self::f<dynamic>() in let final self::B #t40 = #t38.{self::Test::[]}(#t39 as{TypeError} self::Index) in let final void #t41 = #t38.{self::Test::[]=}(#t39 as{TypeError} self::Index, #t40.{self::B::-}(1)) in #t40;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.direct.transformed.expect
new file mode 100644
index 0000000..d8df616
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.direct.transformed.expect
@@ -0,0 +1,63 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Base extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+}
+class Test extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    super.{self::Base::[]=}(self::f<dynamic>(), self::f<dynamic>());
+    let final dynamic #t1 = self::f<dynamic>() in super.{self::Base::[]}(#t1).==(null) ? let final dynamic #t2 = self::f<dynamic>() in let final dynamic #t3 = super.{self::Base::[]=}(#t1, #t2) in #t2 : null;
+    let final dynamic #t4 = self::f<dynamic>() in super.{self::Base::[]=}(#t4, super.{self::Base::[]}(#t4).+(self::f<dynamic>()));
+    let final dynamic #t5 = self::f<dynamic>() in super.{self::Base::[]=}(#t5, super.{self::Base::[]}(#t5).*(self::f<dynamic>()));
+    let final dynamic #t6 = self::f<dynamic>() in super.{self::Base::[]=}(#t6, super.{self::Base::[]}(#t6).&(self::f<dynamic>()));
+    let final dynamic #t7 = self::f<dynamic>() in let final dynamic #t8 = super.{self::Base::[]}(#t7).-(1) in let final dynamic #t9 = super.{self::Base::[]=}(#t7, #t8) in #t8;
+    let final dynamic #t10 = self::f<dynamic>() in super.{self::Base::[]=}(#t10, super.{self::Base::[]}(#t10).-(1));
+    dynamic v1 = let final dynamic #t11 = self::f<dynamic>() in let final dynamic #t12 = self::f<dynamic>() in let final dynamic #t13 = super.{self::Base::[]=}(#t11, #t12) in #t12;
+    dynamic v2 = let final dynamic #t14 = self::f<dynamic>() in let final dynamic #t15 = super.{self::Base::[]}(#t14) in #t15.==(null) ? let final dynamic #t16 = self::f<dynamic>() in let final dynamic #t17 = super.{self::Base::[]=}(#t14, #t16) in #t16 : #t15;
+    dynamic v4 = let final dynamic #t18 = self::f<dynamic>() in let final dynamic #t19 = super.{self::Base::[]}(#t18).*(self::f<dynamic>()) in let final dynamic #t20 = super.{self::Base::[]=}(#t18, #t19) in #t19;
+    dynamic v5 = let final dynamic #t21 = self::f<dynamic>() in let final dynamic #t22 = super.{self::Base::[]}(#t21).&(self::f<dynamic>()) in let final dynamic #t23 = super.{self::Base::[]=}(#t21, #t22) in #t22;
+    dynamic v6 = let final dynamic #t24 = self::f<dynamic>() in let final dynamic #t25 = super.{self::Base::[]}(#t24).-(1) in let final dynamic #t26 = super.{self::Base::[]=}(#t24, #t25) in #t25;
+    dynamic v7 = let final dynamic #t27 = self::f<dynamic>() in let final dynamic #t28 = super.{self::Base::[]}(#t27) in let final dynamic #t29 = super.{self::Base::[]=}(#t27, #t28.-(1)) in #t28;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.transformed.expect
new file mode 100644
index 0000000..1b1837a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_super.dart.strong.transformed.expect
@@ -0,0 +1,63 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Base extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+}
+class Test extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    super.{self::Base::[]=}(self::f<dynamic>() as{TypeError} self::Index, self::f<self::B>());
+    let final dynamic #t1 = self::f<dynamic>() in super.{self::Base::[]}(#t1 as{TypeError} self::Index).{core::Object::==}(null) ?{self::B} let final self::B #t2 = self::f<self::B>() in let final void #t3 = super.{self::Base::[]=}(#t1 as{TypeError} self::Index, #t2) in #t2 : null;
+    let final dynamic #t4 = self::f<dynamic>() in super.{self::Base::[]=}(#t4 as{TypeError} self::Index, super.{self::Base::[]}(#t4 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B);
+    let final dynamic #t5 = self::f<dynamic>() in super.{self::Base::[]=}(#t5 as{TypeError} self::Index, super.{self::Base::[]}(#t5 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B));
+    let final dynamic #t6 = self::f<dynamic>() in super.{self::Base::[]=}(#t6 as{TypeError} self::Index, super.{self::Base::[]}(#t6 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A));
+    let final dynamic #t7 = self::f<dynamic>() in let final self::B #t8 = super.{self::Base::[]}(#t7 as{TypeError} self::Index).{self::B::-}(1) in let final void #t9 = super.{self::Base::[]=}(#t7 as{TypeError} self::Index, #t8) in #t8;
+    let final dynamic #t10 = self::f<dynamic>() in super.{self::Base::[]=}(#t10 as{TypeError} self::Index, super.{self::Base::[]}(#t10 as{TypeError} self::Index).{self::B::-}(1));
+    self::B v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B #t12 = self::f<self::B>() in let final void #t13 = super.{self::Base::[]=}(#t11 as{TypeError} self::Index, #t12) in #t12;
+    self::B v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B #t15 = super.{self::Base::[]}(#t14 as{TypeError} self::Index) in #t15.{core::Object::==}(null) ?{self::B} let final self::B #t16 = self::f<self::B>() in let final void #t17 = super.{self::Base::[]=}(#t14 as{TypeError} self::Index, #t16) in #t16 : #t15;
+    self::B v4 = let final dynamic #t18 = self::f<dynamic>() in let final self::B #t19 = super.{self::Base::[]}(#t18 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B) in let final void #t20 = super.{self::Base::[]=}(#t18 as{TypeError} self::Index, #t19) in #t19;
+    self::C v5 = let final dynamic #t21 = self::f<dynamic>() in let final self::C #t22 = super.{self::Base::[]}(#t21 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A) in let final void #t23 = super.{self::Base::[]=}(#t21 as{TypeError} self::Index, #t22) in #t22;
+    self::B v6 = let final dynamic #t24 = self::f<dynamic>() in let final self::B #t25 = super.{self::Base::[]}(#t24 as{TypeError} self::Index).{self::B::-}(1) in let final void #t26 = super.{self::Base::[]=}(#t24 as{TypeError} self::Index, #t25) in #t25;
+    self::B v7 = let final dynamic #t27 = self::f<dynamic>() in let final self::B #t28 = super.{self::Base::[]}(#t27 as{TypeError} self::Index) in let final void #t29 = super.{self::Base::[]=}(#t27 as{TypeError} self::Index, #t28.{self::B::-}(1)) in #t28;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.direct.transformed.expect
new file mode 100644
index 0000000..80bc52f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.direct.transformed.expect
@@ -0,0 +1,58 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+  method test() → void {
+    this.[]=(self::f<dynamic>(), self::f<dynamic>());
+    let final dynamic #t1 = self::f<dynamic>() in this.[](#t1).==(null) ? let final dynamic #t2 = self::f<dynamic>() in let final dynamic #t3 = this.[]=(#t1, #t2) in #t2 : null;
+    let final dynamic #t4 = self::f<dynamic>() in this.[]=(#t4, this.[](#t4).+(self::f<dynamic>()));
+    let final dynamic #t5 = self::f<dynamic>() in this.[]=(#t5, this.[](#t5).*(self::f<dynamic>()));
+    let final dynamic #t6 = self::f<dynamic>() in this.[]=(#t6, this.[](#t6).&(self::f<dynamic>()));
+    let final dynamic #t7 = self::f<dynamic>() in let final dynamic #t8 = this.[](#t7).-(1) in let final dynamic #t9 = this.[]=(#t7, #t8) in #t8;
+    let final dynamic #t10 = self::f<dynamic>() in this.[]=(#t10, this.[](#t10).-(1));
+    dynamic v1 = let final dynamic #t11 = self::f<dynamic>() in let final dynamic #t12 = self::f<dynamic>() in let final dynamic #t13 = this.[]=(#t11, #t12) in #t12;
+    dynamic v2 = let final dynamic #t14 = self::f<dynamic>() in let final dynamic #t15 = this.[](#t14) in #t15.==(null) ? let final dynamic #t16 = self::f<dynamic>() in let final dynamic #t17 = this.[]=(#t14, #t16) in #t16 : #t15;
+    dynamic v4 = let final dynamic #t18 = self::f<dynamic>() in let final dynamic #t19 = this.[](#t18).*(self::f<dynamic>()) in let final dynamic #t20 = this.[]=(#t18, #t19) in #t19;
+    dynamic v5 = let final dynamic #t21 = self::f<dynamic>() in let final dynamic #t22 = this.[](#t21).&(self::f<dynamic>()) in let final dynamic #t23 = this.[]=(#t21, #t22) in #t22;
+    dynamic v6 = let final dynamic #t24 = self::f<dynamic>() in let final dynamic #t25 = this.[](#t24).-(1) in let final dynamic #t26 = this.[]=(#t24, #t25) in #t25;
+    dynamic v7 = let final dynamic #t27 = self::f<dynamic>() in let final dynamic #t28 = this.[](#t27) in let final dynamic #t29 = this.[]=(#t27, #t28.-(1)) in #t28;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.transformed.expect
new file mode 100644
index 0000000..781c625
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_index_this.dart.strong.transformed.expect
@@ -0,0 +1,58 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+  method test() → void {
+    this.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index, self::f<self::B>());
+    let final dynamic #t1 = self::f<dynamic>() in this.{self::Test::[]}(#t1 as{TypeError} self::Index).{core::Object::==}(null) ?{self::B} let final self::B #t2 = self::f<self::B>() in let final void #t3 = this.{self::Test::[]=}(#t1 as{TypeError} self::Index, #t2) in #t2 : null;
+    let final dynamic #t4 = self::f<dynamic>() in this.{self::Test::[]=}(#t4 as{TypeError} self::Index, this.{self::Test::[]}(#t4 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B);
+    let final dynamic #t5 = self::f<dynamic>() in this.{self::Test::[]=}(#t5 as{TypeError} self::Index, this.{self::Test::[]}(#t5 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B));
+    let final dynamic #t6 = self::f<dynamic>() in this.{self::Test::[]=}(#t6 as{TypeError} self::Index, this.{self::Test::[]}(#t6 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A));
+    let final dynamic #t7 = self::f<dynamic>() in let final self::B #t8 = this.{self::Test::[]}(#t7 as{TypeError} self::Index).{self::B::-}(1) in let final void #t9 = this.{self::Test::[]=}(#t7 as{TypeError} self::Index, #t8) in #t8;
+    let final dynamic #t10 = self::f<dynamic>() in this.{self::Test::[]=}(#t10 as{TypeError} self::Index, this.{self::Test::[]}(#t10 as{TypeError} self::Index).{self::B::-}(1));
+    self::B v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B #t12 = self::f<self::B>() in let final void #t13 = this.{self::Test::[]=}(#t11 as{TypeError} self::Index, #t12) in #t12;
+    self::B v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B #t15 = this.{self::Test::[]}(#t14 as{TypeError} self::Index) in #t15.{core::Object::==}(null) ?{self::B} let final self::B #t16 = self::f<self::B>() in let final void #t17 = this.{self::Test::[]=}(#t14 as{TypeError} self::Index, #t16) in #t16 : #t15;
+    self::B v4 = let final dynamic #t18 = self::f<dynamic>() in let final self::B #t19 = this.{self::Test::[]}(#t18 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B) in let final void #t20 = this.{self::Test::[]=}(#t18 as{TypeError} self::Index, #t19) in #t19;
+    self::C v5 = let final dynamic #t21 = self::f<dynamic>() in let final self::C #t22 = this.{self::Test::[]}(#t21 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A) in let final void #t23 = this.{self::Test::[]=}(#t21 as{TypeError} self::Index, #t22) in #t22;
+    self::B v6 = let final dynamic #t24 = self::f<dynamic>() in let final self::B #t25 = this.{self::Test::[]}(#t24 as{TypeError} self::Index).{self::B::-}(1) in let final void #t26 = this.{self::Test::[]=}(#t24 as{TypeError} self::Index, #t25) in #t25;
+    self::B v7 = let final dynamic #t27 = self::f<dynamic>() in let final self::B #t28 = this.{self::Test::[]}(#t27 as{TypeError} self::Index) in let final void #t29 = this.{self::Test::[]=}(#t27 as{TypeError} self::Index, #t28.{self::B::-}(1)) in #t28;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.direct.transformed.expect
new file mode 100644
index 0000000..3566c8f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.direct.transformed.expect
@@ -0,0 +1,46 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  self::B local;
+  local = self::f<dynamic>();
+  local.==(null) ? local = self::f<dynamic>() : null;
+  local = local.+(self::f<dynamic>());
+  local = local.*(self::f<dynamic>());
+  local = local.&(self::f<dynamic>());
+  local = local.-(1);
+  local = local.-(1);
+  dynamic v1 = local = self::f<dynamic>();
+  dynamic v2 = let final dynamic #t1 = local in #t1.==(null) ? local = self::f<dynamic>() : #t1;
+  dynamic v4 = local = local.*(self::f<dynamic>());
+  dynamic v5 = local = local.&(self::f<dynamic>());
+  dynamic v6 = local = local.-(1);
+  dynamic v7 = let final dynamic #t2 = local in let final dynamic #t3 = local = #t2.-(1) in #t2;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.transformed.expect
new file mode 100644
index 0000000..22bf885
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local.dart.strong.transformed.expect
@@ -0,0 +1,46 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  self::B local;
+  local = self::f<self::B>();
+  local.{core::Object::==}(null) ?{self::B} local = self::f<self::B>() : null;
+  local = local.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+  local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  local = local.{self::B::-}(1);
+  local = local.{self::B::-}(1);
+  self::B v1 = local = self::f<self::B>();
+  self::B v2 = let final self::B #t1 = local in #t1.{core::Object::==}(null) ?{self::B} local = self::f<self::B>() : #t1;
+  self::B v4 = local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  self::C v5 = local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  self::B v6 = local = local.{self::B::-}(1);
+  self::B v7 = let final self::B #t2 = local in let final self::B #t3 = local = #t2.{self::B::-}(1) in #t2;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..7178159
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.direct.transformed.expect
@@ -0,0 +1,40 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method test1(core::int t) → void {
+  dynamic v1 = t = self::getInt();
+  dynamic v4 = let final dynamic #t1 = t in #t1.==(null) ? t = self::getInt() : #t1;
+  dynamic v7 = t = t.+(self::getInt());
+  dynamic v10 = t = t.+(1);
+  dynamic v11 = let final dynamic #t2 = t in let final dynamic #t3 = t = #t2.+(1) in #t2;
+}
+static method test2(core::num t) → void {
+  dynamic v1 = t = self::getInt();
+  dynamic v2 = t = self::getNum();
+  dynamic v3 = t = self::getDouble();
+  dynamic v4 = let final dynamic #t4 = t in #t4.==(null) ? t = self::getInt() : #t4;
+  dynamic v5 = let final dynamic #t5 = t in #t5.==(null) ? t = self::getNum() : #t5;
+  dynamic v6 = let final dynamic #t6 = t in #t6.==(null) ? t = self::getDouble() : #t6;
+  dynamic v7 = t = t.+(self::getInt());
+  dynamic v8 = t = t.+(self::getNum());
+  dynamic v9 = t = t.+(self::getDouble());
+  dynamic v10 = t = t.+(1);
+  dynamic v11 = let final dynamic #t7 = t in let final dynamic #t8 = t = #t7.+(1) in #t7;
+}
+static method test3(core::double t) → void {
+  dynamic v3 = t = self::getDouble();
+  dynamic v6 = let final dynamic #t9 = t in #t9.==(null) ? t = self::getDouble() : #t9;
+  dynamic v7 = t = t.+(self::getInt());
+  dynamic v8 = t = t.+(self::getNum());
+  dynamic v9 = t = t.+(self::getDouble());
+  dynamic v10 = t = t.+(1);
+  dynamic v11 = let final dynamic #t10 = t in let final dynamic #t11 = t = #t10.+(1) in #t10;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..fd38a10
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_local_upwards.dart.strong.transformed.expect
@@ -0,0 +1,40 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method test1(core::int t) → void {
+  core::int v1 = t = self::getInt();
+  core::int v4 = let final core::int #t1 = t in #t1.{core::num::==}(null) ?{core::int} t = self::getInt() : #t1;
+  core::int v7 = t = t.{core::num::+}(self::getInt());
+  core::int v10 = t = t.{core::num::+}(1);
+  core::int v11 = let final core::int #t2 = t in let final core::int #t3 = t = #t2.{core::num::+}(1) in #t2;
+}
+static method test2(core::num t) → void {
+  core::int v1 = t = self::getInt();
+  core::num v2 = t = self::getNum();
+  core::double v3 = t = self::getDouble();
+  core::num v4 = let final core::num #t4 = t in #t4.{core::num::==}(null) ?{core::num} t = self::getInt() : #t4;
+  core::num v5 = let final core::num #t5 = t in #t5.{core::num::==}(null) ?{core::num} t = self::getNum() : #t5;
+  core::num v6 = let final core::num #t6 = t in #t6.{core::num::==}(null) ?{core::num} t = self::getDouble() : #t6;
+  core::num v7 = t = t.{core::num::+}(self::getInt());
+  core::num v8 = t = t.{core::num::+}(self::getNum());
+  core::num v9 = t = t.{core::num::+}(self::getDouble());
+  core::num v10 = t = t.{core::num::+}(1);
+  core::num v11 = let final core::num #t7 = t in let final core::num #t8 = t = #t7.{core::num::+}(1) in #t7;
+}
+static method test3(core::double t) → void {
+  core::double v3 = t = self::getDouble();
+  core::double v6 = let final core::double #t9 = t in #t9.{core::num::==}(null) ?{core::double} t = self::getDouble() : #t9;
+  core::double v7 = t = t.{core::double::+}(self::getInt());
+  core::double v8 = t = t.{core::double::+}(self::getNum());
+  core::double v9 = t = t.{core::double::+}(self::getDouble());
+  core::double v10 = t = t.{core::double::+}(1);
+  core::double v11 = let final core::double #t10 = t in let final core::double #t11 = t = #t10.{core::double::+}(1) in #t10;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.direct.transformed.expect
new file mode 100644
index 0000000..8dd8737
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.direct.transformed.expect
@@ -0,0 +1,51 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test t) → void {
+    t.member = self::f<dynamic>();
+    let final dynamic #t1 = t in #t1.member.==(null) ? #t1.member = self::f<dynamic>() : null;
+    let final dynamic #t2 = t in #t2.member = #t2.member.+(self::f<dynamic>());
+    let final dynamic #t3 = t in #t3.member = #t3.member.*(self::f<dynamic>());
+    let final dynamic #t4 = t in #t4.member = #t4.member.&(self::f<dynamic>());
+    let final dynamic #t5 = t in #t5.member = #t5.member.-(1);
+    let final dynamic #t6 = t in #t6.member = #t6.member.-(1);
+    dynamic v1 = t.member = self::f<dynamic>();
+    dynamic v2 = let final dynamic #t7 = t in let final dynamic #t8 = #t7.member in #t8.==(null) ? #t7.member = self::f<dynamic>() : #t8;
+    dynamic v4 = let final dynamic #t9 = t in #t9.member = #t9.member.*(self::f<dynamic>());
+    dynamic v5 = let final dynamic #t10 = t in #t10.member = #t10.member.&(self::f<dynamic>());
+    dynamic v6 = let final dynamic #t11 = t in #t11.member = #t11.member.-(1);
+    dynamic v7 = let final dynamic #t12 = t in let final dynamic #t13 = #t12.member in let final dynamic #t14 = #t12.member = #t13.-(1) in #t13;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.transformed.expect
new file mode 100644
index 0000000..69aa5fc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_full.dart.strong.transformed.expect
@@ -0,0 +1,51 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test t) → void {
+    t.{self::Test::member} = self::f<self::B>();
+    let final self::Test #t1 = t in #t1.{self::Test::member}.{core::Object::==}(null) ?{self::B} #t1.{self::Test::member} = self::f<self::B>() : null;
+    let final self::Test #t2 = t in #t2.{self::Test::member} = #t2.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    let final self::Test #t3 = t in #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    let final self::Test #t4 = t in #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    let final self::Test #t5 = t in #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::-}(1);
+    let final self::Test #t6 = t in #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
+    self::B v1 = t.{self::Test::member} = self::f<self::B>();
+    self::B v2 = let final self::Test #t7 = t in let final self::B #t8 = #t7.{self::Test::member} in #t8.{core::Object::==}(null) ?{self::B} #t7.{self::Test::member} = self::f<self::B>() : #t8;
+    self::B v4 = let final self::Test #t9 = t in #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    self::C v5 = let final self::Test #t10 = t in #t10.{self::Test::member} = #t10.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    self::B v6 = let final self::Test #t11 = t in #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::-}(1);
+    self::B v7 = let final self::Test #t12 = t in let final self::B #t13 = #t12.{self::Test::member} in let final self::B #t14 = #t12.{self::Test::member} = #t13.{self::B::-}(1) in #t13;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.direct.transformed.expect
new file mode 100644
index 0000000..94d0d64
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.direct.transformed.expect
@@ -0,0 +1,51 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test t) → void {
+    let final dynamic #t1 = t in #t1.==(null) ? null : #t1.member = self::f<dynamic>();
+    let final dynamic #t2 = t in #t2.==(null) ? null : #t2.member.==(null) ? #t2.member = self::f<dynamic>() : null;
+    let final dynamic #t3 = t in #t3.==(null) ? null : #t3.member = #t3.member.+(self::f<dynamic>());
+    let final dynamic #t4 = t in #t4.==(null) ? null : #t4.member = #t4.member.*(self::f<dynamic>());
+    let final dynamic #t5 = t in #t5.==(null) ? null : #t5.member = #t5.member.&(self::f<dynamic>());
+    let final dynamic #t6 = t in #t6.==(null) ? null : #t6.member = #t6.member.-(1);
+    let final dynamic #t7 = t in #t7.==(null) ? null : #t7.member = #t7.member.-(1);
+    dynamic v1 = let final dynamic #t8 = t in #t8.==(null) ? null : #t8.member = self::f<dynamic>();
+    dynamic v2 = let final dynamic #t9 = t in #t9.==(null) ? null : let final dynamic #t10 = #t9.member in #t10.==(null) ? #t9.member = self::f<dynamic>() : #t10;
+    dynamic v4 = let final dynamic #t11 = t in #t11.==(null) ? null : #t11.member = #t11.member.*(self::f<dynamic>());
+    dynamic v5 = let final dynamic #t12 = t in #t12.==(null) ? null : #t12.member = #t12.member.&(self::f<dynamic>());
+    dynamic v6 = let final dynamic #t13 = t in #t13.==(null) ? null : #t13.member = #t13.member.-(1);
+    dynamic v7 = let final dynamic #t14 = t in #t14.==(null) ? null : let final dynamic #t15 = #t14.member in let final dynamic #t16 = #t14.member = #t15.-(1) in #t15;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect
new file mode 100644
index 0000000..941a4b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware.dart.strong.transformed.expect
@@ -0,0 +1,51 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test t) → void {
+    let final self::Test #t1 = t in #t1.==(null) ?{self::B} null : #t1.{self::Test::member} = self::f<self::B>();
+    let final self::Test #t2 = t in #t2.==(null) ?{self::B} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B} #t2.{self::Test::member} = self::f<self::B>() : null;
+    let final self::Test #t3 = t in #t3.==(null) ?{self::A} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    let final self::Test #t4 = t in #t4.==(null) ?{self::B} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    let final self::Test #t5 = t in #t5.==(null) ?{self::C} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    let final self::Test #t6 = t in #t6.==(null) ?{self::B} null : #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
+    let final self::Test #t7 = t in #t7.==(null) ?{self::B} null : #t7.{self::Test::member} = #t7.{self::Test::member}.{self::B::-}(1);
+    self::B v1 = let final self::Test #t8 = t in #t8.==(null) ?{self::B} null : #t8.{self::Test::member} = self::f<self::B>();
+    self::B v2 = let final self::Test #t9 = t in #t9.==(null) ?{self::B} null : let final self::B #t10 = #t9.{self::Test::member} in #t10.{core::Object::==}(null) ?{self::B} #t9.{self::Test::member} = self::f<self::B>() : #t10;
+    self::B v4 = let final self::Test #t11 = t in #t11.==(null) ?{self::B} null : #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    self::C v5 = let final self::Test #t12 = t in #t12.==(null) ?{self::C} null : #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    self::B v6 = let final self::Test #t13 = t in #t13.==(null) ?{self::B} null : #t13.{self::Test::member} = #t13.{self::Test::member}.{self::B::-}(1);
+    self::B v7 = let final self::Test #t14 = t in #t14.==(null) ?{self::B} null : let final self::B #t15 = #t14.{self::Test::member} in let final self::B #t16 = #t14.{self::Test::member} = #t15.{self::B::-}(1) in #t15;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..8cb10cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.direct.transformed.expect
@@ -0,0 +1,58 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test1 t) → void {
+    dynamic v1 = let final dynamic #t1 = t in #t1.==(null) ? null : #t1.prop = self::getInt();
+    dynamic v4 = let final dynamic #t2 = t in #t2.==(null) ? null : let final dynamic #t3 = #t2.prop in #t3.==(null) ? #t2.prop = self::getInt() : #t3;
+    dynamic v7 = let final dynamic #t4 = t in #t4.==(null) ? null : #t4.prop = #t4.prop.+(self::getInt());
+    dynamic v10 = let final dynamic #t5 = t in #t5.==(null) ? null : #t5.prop = #t5.prop.+(1);
+    dynamic v11 = let final dynamic #t6 = t in #t6.==(null) ? null : let final dynamic #t7 = #t6.prop in let final dynamic #t8 = #t6.prop = #t7.+(1) in #t7;
+  }
+}
+class Test2 extends core::Object {
+  field core::num prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test2 t) → void {
+    dynamic v1 = let final dynamic #t9 = t in #t9.==(null) ? null : #t9.prop = self::getInt();
+    dynamic v2 = let final dynamic #t10 = t in #t10.==(null) ? null : #t10.prop = self::getNum();
+    dynamic v3 = let final dynamic #t11 = t in #t11.==(null) ? null : #t11.prop = self::getDouble();
+    dynamic v4 = let final dynamic #t12 = t in #t12.==(null) ? null : let final dynamic #t13 = #t12.prop in #t13.==(null) ? #t12.prop = self::getInt() : #t13;
+    dynamic v5 = let final dynamic #t14 = t in #t14.==(null) ? null : let final dynamic #t15 = #t14.prop in #t15.==(null) ? #t14.prop = self::getNum() : #t15;
+    dynamic v6 = let final dynamic #t16 = t in #t16.==(null) ? null : let final dynamic #t17 = #t16.prop in #t17.==(null) ? #t16.prop = self::getDouble() : #t17;
+    dynamic v7 = let final dynamic #t18 = t in #t18.==(null) ? null : #t18.prop = #t18.prop.+(self::getInt());
+    dynamic v8 = let final dynamic #t19 = t in #t19.==(null) ? null : #t19.prop = #t19.prop.+(self::getNum());
+    dynamic v9 = let final dynamic #t20 = t in #t20.==(null) ? null : #t20.prop = #t20.prop.+(self::getDouble());
+    dynamic v10 = let final dynamic #t21 = t in #t21.==(null) ? null : #t21.prop = #t21.prop.+(1);
+    dynamic v11 = let final dynamic #t22 = t in #t22.==(null) ? null : let final dynamic #t23 = #t22.prop in let final dynamic #t24 = #t22.prop = #t23.+(1) in #t23;
+  }
+}
+class Test3 extends core::Object {
+  field core::double prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test3(self::Test3 t) → void {
+    dynamic v3 = let final dynamic #t25 = t in #t25.==(null) ? null : #t25.prop = self::getDouble();
+    dynamic v6 = let final dynamic #t26 = t in #t26.==(null) ? null : let final dynamic #t27 = #t26.prop in #t27.==(null) ? #t26.prop = self::getDouble() : #t27;
+    dynamic v7 = let final dynamic #t28 = t in #t28.==(null) ? null : #t28.prop = #t28.prop.+(self::getInt());
+    dynamic v8 = let final dynamic #t29 = t in #t29.==(null) ? null : #t29.prop = #t29.prop.+(self::getNum());
+    dynamic v9 = let final dynamic #t30 = t in #t30.==(null) ? null : #t30.prop = #t30.prop.+(self::getDouble());
+    dynamic v10 = let final dynamic #t31 = t in #t31.==(null) ? null : #t31.prop = #t31.prop.+(1);
+    dynamic v11 = let final dynamic #t32 = t in #t32.==(null) ? null : let final dynamic #t33 = #t32.prop in let final dynamic #t34 = #t32.prop = #t33.+(1) in #t33;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..7b5b877
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
@@ -0,0 +1,58 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test1 t) → void {
+    core::int v1 = let final self::Test1 #t1 = t in #t1.==(null) ?{core::int} null : #t1.{self::Test1::prop} = self::getInt();
+    core::int v4 = let final self::Test1 #t2 = t in #t2.==(null) ?{core::int} null : let final core::int #t3 = #t2.{self::Test1::prop} in #t3.{core::num::==}(null) ?{core::int} #t2.{self::Test1::prop} = self::getInt() : #t3;
+    core::int v7 = let final self::Test1 #t4 = t in #t4.==(null) ?{core::int} null : #t4.{self::Test1::prop} = #t4.{self::Test1::prop}.{core::num::+}(self::getInt());
+    core::int v10 = let final self::Test1 #t5 = t in #t5.==(null) ?{core::int} null : #t5.{self::Test1::prop} = #t5.{self::Test1::prop}.{core::num::+}(1);
+    core::int v11 = let final self::Test1 #t6 = t in #t6.==(null) ?{core::int} null : let final core::int #t7 = #t6.{self::Test1::prop} in let final core::int #t8 = #t6.{self::Test1::prop} = #t7.{core::num::+}(1) in #t7;
+  }
+}
+class Test2 extends core::Object {
+  field core::num prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test2 t) → void {
+    core::int v1 = let final self::Test2 #t9 = t in #t9.==(null) ?{core::int} null : #t9.{self::Test2::prop} = self::getInt();
+    core::num v2 = let final self::Test2 #t10 = t in #t10.==(null) ?{core::num} null : #t10.{self::Test2::prop} = self::getNum();
+    core::double v3 = let final self::Test2 #t11 = t in #t11.==(null) ?{core::double} null : #t11.{self::Test2::prop} = self::getDouble();
+    core::num v4 = let final self::Test2 #t12 = t in #t12.==(null) ?{core::num} null : let final core::num #t13 = #t12.{self::Test2::prop} in #t13.{core::num::==}(null) ?{core::num} #t12.{self::Test2::prop} = self::getInt() : #t13;
+    core::num v5 = let final self::Test2 #t14 = t in #t14.==(null) ?{core::num} null : let final core::num #t15 = #t14.{self::Test2::prop} in #t15.{core::num::==}(null) ?{core::num} #t14.{self::Test2::prop} = self::getNum() : #t15;
+    core::num v6 = let final self::Test2 #t16 = t in #t16.==(null) ?{core::num} null : let final core::num #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num} #t16.{self::Test2::prop} = self::getDouble() : #t17;
+    core::num v7 = let final self::Test2 #t18 = t in #t18.==(null) ?{core::num} null : #t18.{self::Test2::prop} = #t18.{self::Test2::prop}.{core::num::+}(self::getInt());
+    core::num v8 = let final self::Test2 #t19 = t in #t19.==(null) ?{core::num} null : #t19.{self::Test2::prop} = #t19.{self::Test2::prop}.{core::num::+}(self::getNum());
+    core::num v9 = let final self::Test2 #t20 = t in #t20.==(null) ?{core::num} null : #t20.{self::Test2::prop} = #t20.{self::Test2::prop}.{core::num::+}(self::getDouble());
+    core::num v10 = let final self::Test2 #t21 = t in #t21.==(null) ?{core::num} null : #t21.{self::Test2::prop} = #t21.{self::Test2::prop}.{core::num::+}(1);
+    core::num v11 = let final self::Test2 #t22 = t in #t22.==(null) ?{core::num} null : let final core::num #t23 = #t22.{self::Test2::prop} in let final core::num #t24 = #t22.{self::Test2::prop} = #t23.{core::num::+}(1) in #t23;
+  }
+}
+class Test3 extends core::Object {
+  field core::double prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test3(self::Test3 t) → void {
+    core::double v3 = let final self::Test3 #t25 = t in #t25.==(null) ?{core::double} null : #t25.{self::Test3::prop} = self::getDouble();
+    core::double v6 = let final self::Test3 #t26 = t in #t26.==(null) ?{core::double} null : let final core::double #t27 = #t26.{self::Test3::prop} in #t27.{core::num::==}(null) ?{core::double} #t26.{self::Test3::prop} = self::getDouble() : #t27;
+    core::double v7 = let final self::Test3 #t28 = t in #t28.==(null) ?{core::double} null : #t28.{self::Test3::prop} = #t28.{self::Test3::prop}.{core::double::+}(self::getInt());
+    core::double v8 = let final self::Test3 #t29 = t in #t29.==(null) ?{core::double} null : #t29.{self::Test3::prop} = #t29.{self::Test3::prop}.{core::double::+}(self::getNum());
+    core::double v9 = let final self::Test3 #t30 = t in #t30.==(null) ?{core::double} null : #t30.{self::Test3::prop} = #t30.{self::Test3::prop}.{core::double::+}(self::getDouble());
+    core::double v10 = let final self::Test3 #t31 = t in #t31.==(null) ?{core::double} null : #t31.{self::Test3::prop} = #t31.{self::Test3::prop}.{core::double::+}(1);
+    core::double v11 = let final self::Test3 #t32 = t in #t32.==(null) ?{core::double} null : let final core::double #t33 = #t32.{self::Test3::prop} in let final core::double #t34 = #t32.{self::Test3::prop} = #t33.{core::double::+}(1) in #t33;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.direct.transformed.expect
new file mode 100644
index 0000000..9f3a3bf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.direct.transformed.expect
@@ -0,0 +1,56 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Base extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Test extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    super.{self::Base::member} = self::f<dynamic>();
+    super.{self::Base::member}.==(null) ? super.{self::Base::member} = self::f<dynamic>() : null;
+    super.{self::Base::member} = super.{self::Base::member}.+(self::f<dynamic>());
+    super.{self::Base::member} = super.{self::Base::member}.*(self::f<dynamic>());
+    super.{self::Base::member} = super.{self::Base::member}.&(self::f<dynamic>());
+    super.{self::Base::member} = super.{self::Base::member}.-(1);
+    super.{self::Base::member} = super.{self::Base::member}.-(1);
+    dynamic v1 = super.{self::Base::member} = self::f<dynamic>();
+    dynamic v2 = let final dynamic #t1 = super.{self::Base::member} in #t1.==(null) ? super.{self::Base::member} = self::f<dynamic>() : #t1;
+    dynamic v4 = super.{self::Base::member} = super.{self::Base::member}.*(self::f<dynamic>());
+    dynamic v5 = super.{self::Base::member} = super.{self::Base::member}.&(self::f<dynamic>());
+    dynamic v6 = super.{self::Base::member} = super.{self::Base::member}.-(1);
+    dynamic v7 = let final dynamic #t2 = super.{self::Base::member} in let final dynamic #t3 = super.{self::Base::member} = #t2.-(1) in #t2;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.transformed.expect
new file mode 100644
index 0000000..65a0233
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super.dart.strong.transformed.expect
@@ -0,0 +1,56 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Base extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Test extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    super.{self::Base::member} = self::f<self::B>();
+    super.{self::Base::member}.{core::Object::==}(null) ?{self::B} super.{self::Base::member} = self::f<self::B>() : null;
+    super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
+    super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
+    self::B v1 = super.{self::Base::member} = self::f<self::B>();
+    self::B v2 = let final self::B #t1 = super.{self::Base::member} in #t1.{core::Object::==}(null) ?{self::B} super.{self::Base::member} = self::f<self::B>() : #t1;
+    self::B v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    self::C v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    self::B v6 = super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
+    self::B v7 = let final self::B #t2 = super.{self::Base::member} in let final self::B #t3 = super.{self::Base::member} = #t2.{self::B::-}(1) in #t2;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..051210b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.direct.transformed.expect
@@ -0,0 +1,63 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  field core::int intProp = null;
+  field core::num numProp = null;
+  field core::double doubleProp = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Test1 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v1 = super.{self::Base::intProp} = self::getInt();
+    dynamic v4 = let final dynamic #t1 = super.{self::Base::intProp} in #t1.==(null) ? super.{self::Base::intProp} = self::getInt() : #t1;
+    dynamic v7 = super.{self::Base::intProp} = super.{self::Base::intProp}.+(self::getInt());
+    dynamic v10 = super.{self::Base::intProp} = super.{self::Base::intProp}.+(1);
+    dynamic v11 = let final dynamic #t2 = super.{self::Base::intProp} in let final dynamic #t3 = super.{self::Base::intProp} = #t2.+(1) in #t2;
+  }
+}
+class Test2 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v1 = super.{self::Base::numProp} = self::getInt();
+    dynamic v2 = super.{self::Base::numProp} = self::getNum();
+    dynamic v3 = super.{self::Base::numProp} = self::getDouble();
+    dynamic v4 = let final dynamic #t4 = super.{self::Base::numProp} in #t4.==(null) ? super.{self::Base::numProp} = self::getInt() : #t4;
+    dynamic v5 = let final dynamic #t5 = super.{self::Base::numProp} in #t5.==(null) ? super.{self::Base::numProp} = self::getNum() : #t5;
+    dynamic v6 = let final dynamic #t6 = super.{self::Base::numProp} in #t6.==(null) ? super.{self::Base::numProp} = self::getDouble() : #t6;
+    dynamic v7 = super.{self::Base::numProp} = super.{self::Base::numProp}.+(self::getInt());
+    dynamic v8 = super.{self::Base::numProp} = super.{self::Base::numProp}.+(self::getNum());
+    dynamic v9 = super.{self::Base::numProp} = super.{self::Base::numProp}.+(self::getDouble());
+    dynamic v10 = super.{self::Base::numProp} = super.{self::Base::numProp}.+(1);
+    dynamic v11 = let final dynamic #t7 = super.{self::Base::numProp} in let final dynamic #t8 = super.{self::Base::numProp} = #t7.+(1) in #t7;
+  }
+}
+class Test3 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test3() → void {
+    dynamic v3 = super.{self::Base::doubleProp} = self::getDouble();
+    dynamic v6 = let final dynamic #t9 = super.{self::Base::doubleProp} in #t9.==(null) ? super.{self::Base::doubleProp} = self::getDouble() : #t9;
+    dynamic v7 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.+(self::getInt());
+    dynamic v8 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.+(self::getNum());
+    dynamic v9 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.+(self::getDouble());
+    dynamic v10 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.+(1);
+    dynamic v11 = let final dynamic #t10 = super.{self::Base::doubleProp} in let final dynamic #t11 = super.{self::Base::doubleProp} = #t10.+(1) in #t10;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..6156050
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_super_upwards.dart.strong.transformed.expect
@@ -0,0 +1,63 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  field core::int intProp = null;
+  field core::num numProp = null;
+  field core::double doubleProp = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Test1 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    core::int v1 = super.{self::Base::intProp} = self::getInt();
+    core::int v4 = let final core::int #t1 = super.{self::Base::intProp} in #t1.{core::num::==}(null) ?{core::int} super.{self::Base::intProp} = self::getInt() : #t1;
+    core::int v7 = super.{self::Base::intProp} = super.{self::Base::intProp}.{core::num::+}(self::getInt());
+    core::int v10 = super.{self::Base::intProp} = super.{self::Base::intProp}.{core::num::+}(1);
+    core::int v11 = let final core::int #t2 = super.{self::Base::intProp} in let final core::int #t3 = super.{self::Base::intProp} = #t2.{core::num::+}(1) in #t2;
+  }
+}
+class Test2 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    core::int v1 = super.{self::Base::numProp} = self::getInt();
+    core::num v2 = super.{self::Base::numProp} = self::getNum();
+    core::double v3 = super.{self::Base::numProp} = self::getDouble();
+    core::num v4 = let final core::num #t4 = super.{self::Base::numProp} in #t4.{core::num::==}(null) ?{core::num} super.{self::Base::numProp} = self::getInt() : #t4;
+    core::num v5 = let final core::num #t5 = super.{self::Base::numProp} in #t5.{core::num::==}(null) ?{core::num} super.{self::Base::numProp} = self::getNum() : #t5;
+    core::num v6 = let final core::num #t6 = super.{self::Base::numProp} in #t6.{core::num::==}(null) ?{core::num} super.{self::Base::numProp} = self::getDouble() : #t6;
+    core::num v7 = super.{self::Base::numProp} = super.{self::Base::numProp}.{core::num::+}(self::getInt());
+    core::num v8 = super.{self::Base::numProp} = super.{self::Base::numProp}.{core::num::+}(self::getNum());
+    core::num v9 = super.{self::Base::numProp} = super.{self::Base::numProp}.{core::num::+}(self::getDouble());
+    core::num v10 = super.{self::Base::numProp} = super.{self::Base::numProp}.{core::num::+}(1);
+    core::num v11 = let final core::num #t7 = super.{self::Base::numProp} in let final core::num #t8 = super.{self::Base::numProp} = #t7.{core::num::+}(1) in #t7;
+  }
+}
+class Test3 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test3() → void {
+    core::double v3 = super.{self::Base::doubleProp} = self::getDouble();
+    core::double v6 = let final core::double #t9 = super.{self::Base::doubleProp} in #t9.{core::num::==}(null) ?{core::double} super.{self::Base::doubleProp} = self::getDouble() : #t9;
+    core::double v7 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.{core::double::+}(self::getInt());
+    core::double v8 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.{core::double::+}(self::getNum());
+    core::double v9 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.{core::double::+}(self::getDouble());
+    core::double v10 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.{core::double::+}(1);
+    core::double v11 = let final core::double #t10 = super.{self::Base::doubleProp} in let final core::double #t11 = super.{self::Base::doubleProp} = #t10.{core::double::+}(1) in #t10;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..adcdb5f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.direct.transformed.expect
@@ -0,0 +1,58 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test1 t) → void {
+    dynamic v1 = t.prop = self::getInt();
+    dynamic v4 = let final dynamic #t1 = t in let final dynamic #t2 = #t1.prop in #t2.==(null) ? #t1.prop = self::getInt() : #t2;
+    dynamic v7 = let final dynamic #t3 = t in #t3.prop = #t3.prop.+(self::getInt());
+    dynamic v10 = let final dynamic #t4 = t in #t4.prop = #t4.prop.+(1);
+    dynamic v11 = let final dynamic #t5 = t in let final dynamic #t6 = #t5.prop in let final dynamic #t7 = #t5.prop = #t6.+(1) in #t6;
+  }
+}
+class Test2 extends core::Object {
+  field core::num prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test2 t) → void {
+    dynamic v1 = t.prop = self::getInt();
+    dynamic v2 = t.prop = self::getNum();
+    dynamic v3 = t.prop = self::getDouble();
+    dynamic v4 = let final dynamic #t8 = t in let final dynamic #t9 = #t8.prop in #t9.==(null) ? #t8.prop = self::getInt() : #t9;
+    dynamic v5 = let final dynamic #t10 = t in let final dynamic #t11 = #t10.prop in #t11.==(null) ? #t10.prop = self::getNum() : #t11;
+    dynamic v6 = let final dynamic #t12 = t in let final dynamic #t13 = #t12.prop in #t13.==(null) ? #t12.prop = self::getDouble() : #t13;
+    dynamic v7 = let final dynamic #t14 = t in #t14.prop = #t14.prop.+(self::getInt());
+    dynamic v8 = let final dynamic #t15 = t in #t15.prop = #t15.prop.+(self::getNum());
+    dynamic v9 = let final dynamic #t16 = t in #t16.prop = #t16.prop.+(self::getDouble());
+    dynamic v10 = let final dynamic #t17 = t in #t17.prop = #t17.prop.+(1);
+    dynamic v11 = let final dynamic #t18 = t in let final dynamic #t19 = #t18.prop in let final dynamic #t20 = #t18.prop = #t19.+(1) in #t19;
+  }
+}
+class Test3 extends core::Object {
+  field core::double prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test3(self::Test3 t) → void {
+    dynamic v3 = t.prop = self::getDouble();
+    dynamic v6 = let final dynamic #t21 = t in let final dynamic #t22 = #t21.prop in #t22.==(null) ? #t21.prop = self::getDouble() : #t22;
+    dynamic v7 = let final dynamic #t23 = t in #t23.prop = #t23.prop.+(self::getInt());
+    dynamic v8 = let final dynamic #t24 = t in #t24.prop = #t24.prop.+(self::getNum());
+    dynamic v9 = let final dynamic #t25 = t in #t25.prop = #t25.prop.+(self::getDouble());
+    dynamic v10 = let final dynamic #t26 = t in #t26.prop = #t26.prop.+(1);
+    dynamic v11 = let final dynamic #t27 = t in let final dynamic #t28 = #t27.prop in let final dynamic #t29 = #t27.prop = #t28.+(1) in #t28;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..2b56047
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_property_upwards.dart.strong.transformed.expect
@@ -0,0 +1,58 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test1 t) → void {
+    core::int v1 = t.{self::Test1::prop} = self::getInt();
+    core::int v4 = let final self::Test1 #t1 = t in let final core::int #t2 = #t1.{self::Test1::prop} in #t2.{core::num::==}(null) ?{core::int} #t1.{self::Test1::prop} = self::getInt() : #t2;
+    core::int v7 = let final self::Test1 #t3 = t in #t3.{self::Test1::prop} = #t3.{self::Test1::prop}.{core::num::+}(self::getInt());
+    core::int v10 = let final self::Test1 #t4 = t in #t4.{self::Test1::prop} = #t4.{self::Test1::prop}.{core::num::+}(1);
+    core::int v11 = let final self::Test1 #t5 = t in let final core::int #t6 = #t5.{self::Test1::prop} in let final core::int #t7 = #t5.{self::Test1::prop} = #t6.{core::num::+}(1) in #t6;
+  }
+}
+class Test2 extends core::Object {
+  field core::num prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test2 t) → void {
+    core::int v1 = t.{self::Test2::prop} = self::getInt();
+    core::num v2 = t.{self::Test2::prop} = self::getNum();
+    core::double v3 = t.{self::Test2::prop} = self::getDouble();
+    core::num v4 = let final self::Test2 #t8 = t in let final core::num #t9 = #t8.{self::Test2::prop} in #t9.{core::num::==}(null) ?{core::num} #t8.{self::Test2::prop} = self::getInt() : #t9;
+    core::num v5 = let final self::Test2 #t10 = t in let final core::num #t11 = #t10.{self::Test2::prop} in #t11.{core::num::==}(null) ?{core::num} #t10.{self::Test2::prop} = self::getNum() : #t11;
+    core::num v6 = let final self::Test2 #t12 = t in let final core::num #t13 = #t12.{self::Test2::prop} in #t13.{core::num::==}(null) ?{core::num} #t12.{self::Test2::prop} = self::getDouble() : #t13;
+    core::num v7 = let final self::Test2 #t14 = t in #t14.{self::Test2::prop} = #t14.{self::Test2::prop}.{core::num::+}(self::getInt());
+    core::num v8 = let final self::Test2 #t15 = t in #t15.{self::Test2::prop} = #t15.{self::Test2::prop}.{core::num::+}(self::getNum());
+    core::num v9 = let final self::Test2 #t16 = t in #t16.{self::Test2::prop} = #t16.{self::Test2::prop}.{core::num::+}(self::getDouble());
+    core::num v10 = let final self::Test2 #t17 = t in #t17.{self::Test2::prop} = #t17.{self::Test2::prop}.{core::num::+}(1);
+    core::num v11 = let final self::Test2 #t18 = t in let final core::num #t19 = #t18.{self::Test2::prop} in let final core::num #t20 = #t18.{self::Test2::prop} = #t19.{core::num::+}(1) in #t19;
+  }
+}
+class Test3 extends core::Object {
+  field core::double prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test3(self::Test3 t) → void {
+    core::double v3 = t.{self::Test3::prop} = self::getDouble();
+    core::double v6 = let final self::Test3 #t21 = t in let final core::double #t22 = #t21.{self::Test3::prop} in #t22.{core::num::==}(null) ?{core::double} #t21.{self::Test3::prop} = self::getDouble() : #t22;
+    core::double v7 = let final self::Test3 #t23 = t in #t23.{self::Test3::prop} = #t23.{self::Test3::prop}.{core::double::+}(self::getInt());
+    core::double v8 = let final self::Test3 #t24 = t in #t24.{self::Test3::prop} = #t24.{self::Test3::prop}.{core::double::+}(self::getNum());
+    core::double v9 = let final self::Test3 #t25 = t in #t25.{self::Test3::prop} = #t25.{self::Test3::prop}.{core::double::+}(self::getDouble());
+    core::double v10 = let final self::Test3 #t26 = t in #t26.{self::Test3::prop} = #t26.{self::Test3::prop}.{core::double::+}(1);
+    core::double v11 = let final self::Test3 #t27 = t in let final core::double #t28 = #t27.{self::Test3::prop} in let final core::double #t29 = #t27.{self::Test3::prop} = #t28.{core::double::+}(1) in #t28;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.direct.transformed.expect
new file mode 100644
index 0000000..aac5dbd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A a = new self::A::•();
+static field dynamic c = 0;
+static method main() → dynamic {
+  self::a;
+  self::c;
+}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.strong.transformed.expect
new file mode 100644
index 0000000..d17dc17
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_ref.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A a = new self::A::•();
+static field core::int c = 0;
+static method main() → dynamic {
+  self::a;
+  self::c;
+}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.direct.transformed.expect
new file mode 100644
index 0000000..f3c9f8d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.direct.transformed.expect
@@ -0,0 +1,62 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  static field self::B staticVariable = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static field self::B topLevelVariable;
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test_topLevelVariable() → void {
+  self::topLevelVariable = self::f<dynamic>();
+  self::topLevelVariable.==(null) ? self::topLevelVariable = self::f<dynamic>() : null;
+  self::topLevelVariable = self::topLevelVariable.+(self::f<dynamic>());
+  self::topLevelVariable = self::topLevelVariable.*(self::f<dynamic>());
+  self::topLevelVariable = self::topLevelVariable.&(self::f<dynamic>());
+  self::topLevelVariable = self::topLevelVariable.-(1);
+  self::topLevelVariable = self::topLevelVariable.-(1);
+  dynamic v1 = self::topLevelVariable = self::f<dynamic>();
+  dynamic v2 = let final dynamic #t1 = self::topLevelVariable in #t1.==(null) ? self::topLevelVariable = self::f<dynamic>() : #t1;
+  dynamic v4 = self::topLevelVariable = self::topLevelVariable.*(self::f<dynamic>());
+  dynamic v5 = self::topLevelVariable = self::topLevelVariable.&(self::f<dynamic>());
+  dynamic v6 = self::topLevelVariable = self::topLevelVariable.-(1);
+  dynamic v7 = let final dynamic #t2 = self::topLevelVariable in let final dynamic #t3 = self::topLevelVariable = #t2.-(1) in #t2;
+}
+static method test_staticVariable() → void {
+  self::B::staticVariable = self::f<dynamic>();
+  self::B::staticVariable.==(null) ? self::B::staticVariable = self::f<dynamic>() : null;
+  self::B::staticVariable = self::B::staticVariable.+(self::f<dynamic>());
+  self::B::staticVariable = self::B::staticVariable.*(self::f<dynamic>());
+  self::B::staticVariable = self::B::staticVariable.&(self::f<dynamic>());
+  self::B::staticVariable = self::B::staticVariable.-(1);
+  self::B::staticVariable = self::B::staticVariable.-(1);
+  dynamic v1 = self::B::staticVariable = self::f<dynamic>();
+  dynamic v2 = let final dynamic #t4 = self::B::staticVariable in #t4.==(null) ? self::B::staticVariable = self::f<dynamic>() : #t4;
+  dynamic v4 = self::B::staticVariable = self::B::staticVariable.*(self::f<dynamic>());
+  dynamic v5 = self::B::staticVariable = self::B::staticVariable.&(self::f<dynamic>());
+  dynamic v6 = self::B::staticVariable = self::B::staticVariable.-(1);
+  dynamic v7 = let final dynamic #t5 = self::B::staticVariable in let final dynamic #t6 = self::B::staticVariable = #t5.-(1) in #t5;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.transformed.expect
new file mode 100644
index 0000000..e66e6c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  static field self::B staticVariable = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static field self::B topLevelVariable;
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test_topLevelVariable() → void {
+  self::topLevelVariable = self::f<self::B>();
+  self::topLevelVariable.{core::Object::==}(null) ?{self::B} self::topLevelVariable = self::f<self::B>() : null;
+  self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+  self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
+  self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
+  self::B v1 = self::topLevelVariable = self::f<self::B>();
+  self::B v2 = let final self::B #t1 = self::topLevelVariable in #t1.{core::Object::==}(null) ?{self::B} self::topLevelVariable = self::f<self::B>() : #t1;
+  self::B v4 = self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  self::C v5 = self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  self::B v6 = self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
+  self::B v7 = let final self::B #t2 = self::topLevelVariable in let final self::B #t3 = self::topLevelVariable = #t2.{self::B::-}(1) in #t2;
+}
+static method test_staticVariable() → void {
+  self::B::staticVariable = self::f<self::B>();
+  self::B::staticVariable.{core::Object::==}(null) ?{self::B} self::B::staticVariable = self::f<self::B>() : null;
+  self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+  self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
+  self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
+  self::B v1 = self::B::staticVariable = self::f<self::B>();
+  self::B v2 = let final self::B #t4 = self::B::staticVariable in #t4.{core::Object::==}(null) ?{self::B} self::B::staticVariable = self::f<self::B>() : #t4;
+  self::B v4 = self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  self::C v5 = self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  self::B v6 = self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
+  self::B v7 = let final self::B #t5 = self::B::staticVariable in let final self::B #t6 = self::B::staticVariable = #t5.{self::B::-}(1) in #t5;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..5998ee6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.direct.transformed.expect
@@ -0,0 +1,43 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int topLevelInt;
+static field core::num topLevelNum;
+static field core::double topLevelDouble;
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method test1() → void {
+  dynamic v1 = self::topLevelInt = self::getInt();
+  dynamic v4 = let final dynamic #t1 = self::topLevelInt in #t1.==(null) ? self::topLevelInt = self::getInt() : #t1;
+  dynamic v7 = self::topLevelInt = self::topLevelInt.+(self::getInt());
+  dynamic v10 = self::topLevelInt = self::topLevelInt.+(1);
+  dynamic v11 = let final dynamic #t2 = self::topLevelInt in let final dynamic #t3 = self::topLevelInt = #t2.+(1) in #t2;
+}
+static method test2() → void {
+  dynamic v1 = self::topLevelNum = self::getInt();
+  dynamic v2 = self::topLevelNum = self::getNum();
+  dynamic v3 = self::topLevelNum = self::getDouble();
+  dynamic v4 = let final dynamic #t4 = self::topLevelNum in #t4.==(null) ? self::topLevelNum = self::getInt() : #t4;
+  dynamic v5 = let final dynamic #t5 = self::topLevelNum in #t5.==(null) ? self::topLevelNum = self::getNum() : #t5;
+  dynamic v6 = let final dynamic #t6 = self::topLevelNum in #t6.==(null) ? self::topLevelNum = self::getDouble() : #t6;
+  dynamic v7 = self::topLevelNum = self::topLevelNum.+(self::getInt());
+  dynamic v8 = self::topLevelNum = self::topLevelNum.+(self::getNum());
+  dynamic v9 = self::topLevelNum = self::topLevelNum.+(self::getDouble());
+  dynamic v10 = self::topLevelNum = self::topLevelNum.+(1);
+  dynamic v11 = let final dynamic #t7 = self::topLevelNum in let final dynamic #t8 = self::topLevelNum = #t7.+(1) in #t7;
+}
+static method test3() → void {
+  dynamic v3 = self::topLevelDouble = self::getDouble();
+  dynamic v6 = let final dynamic #t9 = self::topLevelDouble in #t9.==(null) ? self::topLevelDouble = self::getDouble() : #t9;
+  dynamic v7 = self::topLevelDouble = self::topLevelDouble.+(self::getInt());
+  dynamic v8 = self::topLevelDouble = self::topLevelDouble.+(self::getNum());
+  dynamic v9 = self::topLevelDouble = self::topLevelDouble.+(self::getDouble());
+  dynamic v10 = self::topLevelDouble = self::topLevelDouble.+(1);
+  dynamic v11 = let final dynamic #t10 = self::topLevelDouble in let final dynamic #t11 = self::topLevelDouble = #t10.+(1) in #t10;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..7122b49
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_assign_to_static_upwards.dart.strong.transformed.expect
@@ -0,0 +1,43 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int topLevelInt;
+static field core::num topLevelNum;
+static field core::double topLevelDouble;
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method test1() → void {
+  core::int v1 = self::topLevelInt = self::getInt();
+  core::int v4 = let final core::int #t1 = self::topLevelInt in #t1.{core::num::==}(null) ?{core::int} self::topLevelInt = self::getInt() : #t1;
+  core::int v7 = self::topLevelInt = self::topLevelInt.{core::num::+}(self::getInt());
+  core::int v10 = self::topLevelInt = self::topLevelInt.{core::num::+}(1);
+  core::int v11 = let final core::int #t2 = self::topLevelInt in let final core::int #t3 = self::topLevelInt = #t2.{core::num::+}(1) in #t2;
+}
+static method test2() → void {
+  core::int v1 = self::topLevelNum = self::getInt();
+  core::num v2 = self::topLevelNum = self::getNum();
+  core::double v3 = self::topLevelNum = self::getDouble();
+  core::num v4 = let final core::num #t4 = self::topLevelNum in #t4.{core::num::==}(null) ?{core::num} self::topLevelNum = self::getInt() : #t4;
+  core::num v5 = let final core::num #t5 = self::topLevelNum in #t5.{core::num::==}(null) ?{core::num} self::topLevelNum = self::getNum() : #t5;
+  core::num v6 = let final core::num #t6 = self::topLevelNum in #t6.{core::num::==}(null) ?{core::num} self::topLevelNum = self::getDouble() : #t6;
+  core::num v7 = self::topLevelNum = self::topLevelNum.{core::num::+}(self::getInt());
+  core::num v8 = self::topLevelNum = self::topLevelNum.{core::num::+}(self::getNum());
+  core::num v9 = self::topLevelNum = self::topLevelNum.{core::num::+}(self::getDouble());
+  core::num v10 = self::topLevelNum = self::topLevelNum.{core::num::+}(1);
+  core::num v11 = let final core::num #t7 = self::topLevelNum in let final core::num #t8 = self::topLevelNum = #t7.{core::num::+}(1) in #t7;
+}
+static method test3() → void {
+  core::double v3 = self::topLevelDouble = self::getDouble();
+  core::double v6 = let final core::double #t9 = self::topLevelDouble in #t9.{core::num::==}(null) ?{core::double} self::topLevelDouble = self::getDouble() : #t9;
+  core::double v7 = self::topLevelDouble = self::topLevelDouble.{core::double::+}(self::getInt());
+  core::double v8 = self::topLevelDouble = self::topLevelDouble.{core::double::+}(self::getNum());
+  core::double v9 = self::topLevelDouble = self::topLevelDouble.{core::double::+}(self::getDouble());
+  core::double v10 = self::topLevelDouble = self::topLevelDouble.{core::double::+}(1);
+  core::double v11 = let final core::double #t10 = self::topLevelDouble in let final core::double #t11 = self::topLevelDouble = #t10.{core::double::+}(1) in #t10;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_binary_custom.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_binary_custom.dart.direct.transformed.expect
new file mode 100644
index 0000000..001ba76
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_custom.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → core::int
+    return 1;
+  operator -(dynamic other) → core::double
+    return 2.0;
+}
+static field dynamic v_add = new self::A::•().+("foo");
+static field dynamic v_minus = new self::A::•().-("bar");
+static method main() → dynamic {
+  self::v_add;
+  self::v_minus;
+}
diff --git a/pkg/front_end/testcases/inference/infer_binary_custom.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_binary_custom.dart.strong.transformed.expect
new file mode 100644
index 0000000..13a93a6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_custom.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → core::int
+    return 1;
+  operator -(dynamic other) → core::double
+    return 2.0;
+}
+static field core::int v_add = new self::A::•().{self::A::+}("foo");
+static field core::double v_minus = new self::A::•().{self::A::-}("bar");
+static method main() → dynamic {
+  self::v_add;
+  self::v_minus;
+}
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_double.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.direct.transformed.expect
new file mode 100644
index 0000000..a1b8822
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.direct.transformed.expect
@@ -0,0 +1,29 @@
+library test;
+import self as self;
+
+static field dynamic a_equal = 1.0.==(2.0);
+static field dynamic a_notEqual = !1.0.==(2.0);
+static field dynamic a_add = 1.0.+(2.0);
+static field dynamic a_subtract = 1.0.-(2.0);
+static field dynamic a_multiply = 1.0.*(2.0);
+static field dynamic a_divide = 1.0./(2.0);
+static field dynamic a_floorDivide = 1.0.~/(2.0);
+static field dynamic a_greater = 1.0.>(2.0);
+static field dynamic a_less = 1.0.<(2.0);
+static field dynamic a_greaterEqual = 1.0.>=(2.0);
+static field dynamic a_lessEqual = 1.0.<=(2.0);
+static field dynamic a_modulo = 1.0.%(2.0);
+static method main() → dynamic {
+  self::a_equal;
+  self::a_notEqual;
+  self::a_add;
+  self::a_subtract;
+  self::a_multiply;
+  self::a_divide;
+  self::a_floorDivide;
+  self::a_greater;
+  self::a_less;
+  self::a_greaterEqual;
+  self::a_lessEqual;
+  self::a_modulo;
+}
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_double.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.strong.transformed.expect
new file mode 100644
index 0000000..b489197
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_double.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::bool a_equal = 1.0.{core::num::==}(2.0);
+static field core::bool a_notEqual = !1.0.{core::num::==}(2.0);
+static field core::double a_add = 1.0.{core::double::+}(2.0);
+static field core::double a_subtract = 1.0.{core::double::-}(2.0);
+static field core::double a_multiply = 1.0.{core::double::*}(2.0);
+static field core::double a_divide = 1.0.{core::double::/}(2.0);
+static field core::int a_floorDivide = 1.0.{core::double::~/}(2.0);
+static field core::bool a_greater = 1.0.{core::num::>}(2.0);
+static field core::bool a_less = 1.0.{core::num::<}(2.0);
+static field core::bool a_greaterEqual = 1.0.{core::num::>=}(2.0);
+static field core::bool a_lessEqual = 1.0.{core::num::<=}(2.0);
+static field core::double a_modulo = 1.0.{core::double::%}(2.0);
+static method main() → dynamic {
+  self::a_equal;
+  self::a_notEqual;
+  self::a_add;
+  self::a_subtract;
+  self::a_multiply;
+  self::a_divide;
+  self::a_floorDivide;
+  self::a_greater;
+  self::a_less;
+  self::a_greaterEqual;
+  self::a_lessEqual;
+  self::a_modulo;
+}
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_int.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.direct.transformed.expect
new file mode 100644
index 0000000..6654e67
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.direct.transformed.expect
@@ -0,0 +1,29 @@
+library test;
+import self as self;
+
+static field dynamic a_equal = 1.0.==(2);
+static field dynamic a_notEqual = !1.0.==(2);
+static field dynamic a_add = 1.0.+(2);
+static field dynamic a_subtract = 1.0.-(2);
+static field dynamic a_multiply = 1.0.*(2);
+static field dynamic a_divide = 1.0./(2);
+static field dynamic a_floorDivide = 1.0.~/(2);
+static field dynamic a_greater = 1.0.>(2);
+static field dynamic a_less = 1.0.<(2);
+static field dynamic a_greaterEqual = 1.0.>=(2);
+static field dynamic a_lessEqual = 1.0.<=(2);
+static field dynamic a_modulo = 1.0.%(2);
+static method main() → dynamic {
+  self::a_equal;
+  self::a_notEqual;
+  self::a_add;
+  self::a_subtract;
+  self::a_multiply;
+  self::a_divide;
+  self::a_floorDivide;
+  self::a_greater;
+  self::a_less;
+  self::a_greaterEqual;
+  self::a_lessEqual;
+  self::a_modulo;
+}
diff --git a/pkg/front_end/testcases/inference/infer_binary_double_int.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.strong.transformed.expect
new file mode 100644
index 0000000..2c6049e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_double_int.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::bool a_equal = 1.0.{core::num::==}(2);
+static field core::bool a_notEqual = !1.0.{core::num::==}(2);
+static field core::double a_add = 1.0.{core::double::+}(2);
+static field core::double a_subtract = 1.0.{core::double::-}(2);
+static field core::double a_multiply = 1.0.{core::double::*}(2);
+static field core::double a_divide = 1.0.{core::double::/}(2);
+static field core::int a_floorDivide = 1.0.{core::double::~/}(2);
+static field core::bool a_greater = 1.0.{core::num::>}(2);
+static field core::bool a_less = 1.0.{core::num::<}(2);
+static field core::bool a_greaterEqual = 1.0.{core::num::>=}(2);
+static field core::bool a_lessEqual = 1.0.{core::num::<=}(2);
+static field core::double a_modulo = 1.0.{core::double::%}(2);
+static method main() → dynamic {
+  self::a_equal;
+  self::a_notEqual;
+  self::a_add;
+  self::a_subtract;
+  self::a_multiply;
+  self::a_divide;
+  self::a_floorDivide;
+  self::a_greater;
+  self::a_less;
+  self::a_greaterEqual;
+  self::a_lessEqual;
+  self::a_modulo;
+}
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_double.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.direct.transformed.expect
new file mode 100644
index 0000000..688ef78
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.direct.transformed.expect
@@ -0,0 +1,29 @@
+library test;
+import self as self;
+
+static field dynamic a_equal = 1.==(2.0);
+static field dynamic a_notEqual = !1.==(2.0);
+static field dynamic a_add = 1.+(2.0);
+static field dynamic a_subtract = 1.-(2.0);
+static field dynamic a_multiply = 1.*(2.0);
+static field dynamic a_divide = 1./(2.0);
+static field dynamic a_floorDivide = 1.~/(2.0);
+static field dynamic a_greater = 1.>(2.0);
+static field dynamic a_less = 1.<(2.0);
+static field dynamic a_greaterEqual = 1.>=(2.0);
+static field dynamic a_lessEqual = 1.<=(2.0);
+static field dynamic a_modulo = 1.%(2.0);
+static method main() → dynamic {
+  self::a_equal;
+  self::a_notEqual;
+  self::a_add;
+  self::a_subtract;
+  self::a_multiply;
+  self::a_divide;
+  self::a_floorDivide;
+  self::a_greater;
+  self::a_less;
+  self::a_greaterEqual;
+  self::a_lessEqual;
+  self::a_modulo;
+}
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_double.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.strong.transformed.expect
new file mode 100644
index 0000000..c85b938
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_double.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::bool a_equal = 1.{core::num::==}(2.0);
+static field core::bool a_notEqual = !1.{core::num::==}(2.0);
+static field core::double a_add = 1.{core::num::+}(2.0);
+static field core::double a_subtract = 1.{core::num::-}(2.0);
+static field core::double a_multiply = 1.{core::num::*}(2.0);
+static field core::double a_divide = 1.{core::num::/}(2.0);
+static field core::int a_floorDivide = 1.{core::num::~/}(2.0);
+static field core::bool a_greater = 1.{core::num::>}(2.0);
+static field core::bool a_less = 1.{core::num::<}(2.0);
+static field core::bool a_greaterEqual = 1.{core::num::>=}(2.0);
+static field core::bool a_lessEqual = 1.{core::num::<=}(2.0);
+static field core::double a_modulo = 1.{core::num::%}(2.0);
+static method main() → dynamic {
+  self::a_equal;
+  self::a_notEqual;
+  self::a_add;
+  self::a_subtract;
+  self::a_multiply;
+  self::a_divide;
+  self::a_floorDivide;
+  self::a_greater;
+  self::a_less;
+  self::a_greaterEqual;
+  self::a_lessEqual;
+  self::a_modulo;
+}
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_int.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.direct.transformed.expect
new file mode 100644
index 0000000..29574bd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.direct.transformed.expect
@@ -0,0 +1,39 @@
+library test;
+import self as self;
+
+static field dynamic a_equal = 1.==(2);
+static field dynamic a_notEqual = !1.==(2);
+static field dynamic a_bitXor = 1.^(2);
+static field dynamic a_bitAnd = 1.&(2);
+static field dynamic a_bitOr = 1.|(2);
+static field dynamic a_bitShiftRight = 1.>>(2);
+static field dynamic a_bitShiftLeft = 1.<<(2);
+static field dynamic a_add = 1.+(2);
+static field dynamic a_subtract = 1.-(2);
+static field dynamic a_multiply = 1.*(2);
+static field dynamic a_divide = 1./(2);
+static field dynamic a_floorDivide = 1.~/(2);
+static field dynamic a_greater = 1.>(2);
+static field dynamic a_less = 1.<(2);
+static field dynamic a_greaterEqual = 1.>=(2);
+static field dynamic a_lessEqual = 1.<=(2);
+static field dynamic a_modulo = 1.%(2);
+static method main() → dynamic {
+  self::a_equal;
+  self::a_notEqual;
+  self::a_bitXor;
+  self::a_bitAnd;
+  self::a_bitOr;
+  self::a_bitShiftRight;
+  self::a_bitShiftLeft;
+  self::a_add;
+  self::a_subtract;
+  self::a_multiply;
+  self::a_divide;
+  self::a_floorDivide;
+  self::a_greater;
+  self::a_less;
+  self::a_greaterEqual;
+  self::a_lessEqual;
+  self::a_modulo;
+}
diff --git a/pkg/front_end/testcases/inference/infer_binary_int_int.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.strong.transformed.expect
new file mode 100644
index 0000000..58fb222
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_binary_int_int.dart.strong.transformed.expect
@@ -0,0 +1,40 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::bool a_equal = 1.{core::num::==}(2);
+static field core::bool a_notEqual = !1.{core::num::==}(2);
+static field core::int a_bitXor = 1.{core::int::^}(2);
+static field core::int a_bitAnd = 1.{core::int::&}(2);
+static field core::int a_bitOr = 1.{core::int::|}(2);
+static field core::int a_bitShiftRight = 1.{core::int::>>}(2);
+static field core::int a_bitShiftLeft = 1.{core::int::<<}(2);
+static field core::int a_add = 1.{core::num::+}(2);
+static field core::int a_subtract = 1.{core::num::-}(2);
+static field core::int a_multiply = 1.{core::num::*}(2);
+static field core::double a_divide = 1.{core::num::/}(2);
+static field core::int a_floorDivide = 1.{core::num::~/}(2);
+static field core::bool a_greater = 1.{core::num::>}(2);
+static field core::bool a_less = 1.{core::num::<}(2);
+static field core::bool a_greaterEqual = 1.{core::num::>=}(2);
+static field core::bool a_lessEqual = 1.{core::num::<=}(2);
+static field core::int a_modulo = 1.{core::num::%}(2);
+static method main() → dynamic {
+  self::a_equal;
+  self::a_notEqual;
+  self::a_bitXor;
+  self::a_bitAnd;
+  self::a_bitOr;
+  self::a_bitShiftRight;
+  self::a_bitShiftLeft;
+  self::a_add;
+  self::a_subtract;
+  self::a_multiply;
+  self::a_divide;
+  self::a_floorDivide;
+  self::a_greater;
+  self::a_less;
+  self::a_greaterEqual;
+  self::a_lessEqual;
+  self::a_modulo;
+}
diff --git a/pkg/front_end/testcases/inference/infer_conditional.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_conditional.dart.direct.transformed.expect
new file mode 100644
index 0000000..bc0914a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_conditional.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+
+static field dynamic a = 1.==(2) ? 1 : 2.0;
+static field dynamic b = 1.==(2) ? 1.0 : 2;
+static method main() → dynamic {
+  self::a;
+  self::b;
+}
diff --git a/pkg/front_end/testcases/inference/infer_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_conditional.dart.strong.transformed.expect
new file mode 100644
index 0000000..7a49b3e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_conditional.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::num a = 1.{core::num::==}(2) ?{core::num} 1 : 2.0;
+static field core::num b = 1.{core::num::==}(2) ?{core::num} 1.0 : 2;
+static method main() → dynamic {
+  self::a;
+  self::b;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..bd2face
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_consts_transitively_2_a.dart" as inf;
+
+static const field dynamic m1 = inf::a1;
+static const field dynamic m2 = inf::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = self::m1;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..964f93d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_consts_transitively_2_a.dart" as inf;
+
+static const field core::int m1 = inf::a1;
+static const field core::int m2 = inf::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = self::m1;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.direct.transformed.expect
new file mode 100644
index 0000000..49f30fa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./infer_consts_transitively_2.dart" as test;
+import "./infer_consts_transitively_2_b.dart" as inf;
+
+static const field dynamic a1 = test::m2;
+static const field dynamic a2 = inf::b1;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect
new file mode 100644
index 0000000..169b4c2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_a.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./infer_consts_transitively_2.dart" as test;
+import "./infer_consts_transitively_2_b.dart" as inf;
+
+static const field core::int a1 = test::m2;
+static const field core::int a2 = inf::b1;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.direct.transformed.expect
new file mode 100644
index 0000000..335fe8e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static const field dynamic b1 = 2;
+static method main() → dynamic {
+  self::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.strong.transformed.expect
new file mode 100644
index 0000000..b60ae23
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_2_b.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field core::int b1 = 2;
+static method main() → dynamic {
+  self::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.direct.transformed.expect
new file mode 100644
index 0000000..335fe8e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static const field dynamic b1 = 2;
+static method main() → dynamic {
+  self::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.strong.transformed.expect
new file mode 100644
index 0000000..b60ae23
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_consts_transitively_b.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field core::int b1 = 2;
+static method main() → dynamic {
+  self::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.direct.transformed.expect
new file mode 100644
index 0000000..347b333
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic x = null;
+  field dynamic y = 2;
+  field dynamic z = "hi";
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A {
+  field dynamic x = 2;
+  field dynamic y = 3;
+  field dynamic z = null;
+  field dynamic w = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic {
+  core::String s;
+  core::int i;
+  s = new self::B::•().x;
+  s = new self::B::•().y;
+  s = new self::B::•().z;
+  s = new self::B::•().w;
+  i = new self::B::•().x;
+  i = new self::B::•().y;
+  i = new self::B::•().z;
+  i = new self::B::•().w;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
new file mode 100644
index 0000000..b4bc4025
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart.strong.transformed.expect
@@ -0,0 +1,43 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic x = null;
+  field core::int y = 2;
+  field core::String z = "hi";
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A {
+  field dynamic x = 2;
+  field core::int y = 3;
+  field core::String z = null;
+  field core::int w = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic {
+  core::String s;
+  core::int i;
+  s = new self::B::•().{self::B::x} as{TypeError} core::String;
+  s = let final core::int #t1 = new self::B::•().{self::B::y} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:26:62: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::y*/ y;
+                                                             ^";
+  s = new self::B::•().{self::B::z};
+  s = let final core::int #t2 = new self::B::•().{self::B::w} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:28:62: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  s = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::w*/ w;
+                                                             ^";
+  i = new self::B::•().{self::B::x} as{TypeError} core::int;
+  i = new self::B::•().{self::B::y};
+  i = let final core::String #t3 = new self::B::•().{self::B::z} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_correctly_on_multiple_variables_declared_together.dart:32:62: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  i = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::z*/ z;
+                                                             ^";
+  i = new self::B::•().{self::B::w};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..08cf7fa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field dynamic x = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..86a7e29
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_field.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field core::int x = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.direct.transformed.expect
new file mode 100644
index 0000000..d3f0a00
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class B extends core::Object implements self::C {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → dynamic;
+}
+abstract class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.strong.transformed.expect
new file mode 100644
index 0000000..047eb54
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_getter.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class B extends core::Object implements self::C {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+abstract class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..b5f0be8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class B extends core::Object implements self::C {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(dynamic value) → void;
+}
+abstract class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::int value) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..314011d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_from_later_inferred_setter.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class B extends core::Object implements self::C {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::int value) → void;
+}
+abstract class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::int value) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.direct.transformed.expect
new file mode 100644
index 0000000..df402bc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_multiple.dart.direct.transformed.expect
@@ -0,0 +1,53 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+abstract class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::num;
+}
+abstract class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::double;
+}
+class E extends self::A implements self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class F extends self::A implements self::C {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class G extends self::A implements self::D {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class H extends self::C implements self::D {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.direct.transformed.expect
new file mode 100644
index 0000000..e345b97
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::num;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract get x() → core::int;
+}
+class C extends self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.strong.transformed.expect
new file mode 100644
index 0000000..3c4ae25
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_of_override.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::num;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract get x() → core::int;
+}
+class C extends self::B {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.direct.transformed.expect
new file mode 100644
index 0000000..de0ee9c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<T extends core::Object> extends core::Object {
+  field core::List<self::A::T> z = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::List<self::A::T>;
+  abstract set y(core::List<self::A::T> value) → void;
+}
+class B extends self::A<core::int> {
+  field dynamic x = null;
+  field dynamic y = null;
+  field dynamic z = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.strong.transformed.expect
new file mode 100644
index 0000000..e1b8859
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_override_with_substitution.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field core::List<self::A::T> z = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::List<self::A::T>;
+  abstract set y(generic-covariant-impl generic-covariant-interface core::List<self::A::T> value) → void;
+}
+class B extends self::A<core::int> {
+  field core::List<core::int> x = null;
+  generic-covariant-impl field core::List<core::int> y = null;
+  generic-covariant-impl field core::List<core::int> z = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.direct.transformed.expect
new file mode 100644
index 0000000..3a9c949
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.direct.transformed.expect
@@ -0,0 +1,55 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+class C extends self::A {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class D extends self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class E extends core::Object implements self::A {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends core::Object implements self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _G&Object&B extends core::Object implements self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+class G extends self::_G&Object&B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.strong.transformed.expect
new file mode 100644
index 0000000..1669c26
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_getter.dart.strong.transformed.expect
@@ -0,0 +1,55 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+class C extends self::A {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class D extends self::B {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class E extends core::Object implements self::A {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends core::Object implements self::B {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _G&Object&B extends core::Object implements self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+class G extends self::_G&Object&B {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..174b0fe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.direct.transformed.expect
@@ -0,0 +1,53 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::int value) → void;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int value) → void {}
+}
+class C extends self::A {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class D extends self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class E extends core::Object implements self::A {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends core::Object implements self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _G&Object&B extends core::Object implements self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int value) → void {}
+}
+class G extends self::_G&Object&B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..97edcbc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_overrides_setter.dart.strong.transformed.expect
@@ -0,0 +1,53 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::int value) → void;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int value) → void {}
+}
+class C extends self::A {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class D extends self::B {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class E extends core::Object implements self::A {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends core::Object implements self::B {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _G&Object&B extends core::Object implements self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int value) → void {}
+}
+class G extends self::_G&Object&B {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_static.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_field_static.dart.direct.transformed.expect
new file mode 100644
index 0000000..3ae2bbb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_static.dart.direct.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static get x() → core::int
+    return 0;
+}
+class B extends self::A {
+  static field dynamic x = self::f();
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends self::A {
+  static field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method f() → dynamic
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_field_static.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_field_static.dart.strong.transformed.expect
new file mode 100644
index 0000000..3ae2bbb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_field_static.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static get x() → core::int
+    return 0;
+}
+class B extends self::A {
+  static field dynamic x = self::f();
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends self::A {
+  static field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method f() → dynamic
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..ade9351
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+  abstract set x(core::double value) → void;
+}
+class B extends self::A {
+  final field dynamic x;
+  constructor •(dynamic x) → void
+    : self::B::x = x, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..e5bc744
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_and_setter.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+  abstract set x(core::double value) → void;
+}
+class B extends self::A {
+  final field core::int x;
+  constructor •(core::int x) → void
+    : self::B::x = x, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.direct.transformed.expect
new file mode 100644
index 0000000..607a12e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+class B extends self::A {
+  final field dynamic x;
+  constructor •(dynamic x) → void
+    : self::B::x = x, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.strong.transformed.expect
new file mode 100644
index 0000000..b2351c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_getter_only.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+class B extends self::A {
+  final field core::int x;
+  constructor •(core::int x) → void
+    : self::B::x = x, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.transformed.expect
new file mode 100644
index 0000000..eaabbd8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::double value) → void;
+}
+class B extends self::A {
+  final field dynamic x;
+  constructor •(dynamic x) → void
+    : self::B::x = x, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.transformed.expect
new file mode 100644
index 0000000..e666cdd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_final_field_setter_only.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::double value) → void;
+}
+class B extends self::A {
+  final field core::double x;
+  constructor •(core::double x) → void
+    : self::B::x = x, super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.direct.transformed.expect
new file mode 100644
index 0000000..8876de4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.direct.transformed.expect
@@ -0,0 +1,53 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → self::B
+    return null;
+}
+class B extends self::A {
+  constructor •(dynamic ignore) → void
+    : super self::A::•()
+    ;
+}
+static field dynamic a = new self::A::•();
+static field dynamic b = new self::B::•(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#x, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+static field dynamic c1 = <dynamic>[throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#x, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))];
+static field dynamic c2 = const <dynamic>[];
+static field dynamic d = <dynamic, dynamic>{"a": "b"};
+static field dynamic e = let final dynamic #t1 = new self::A::•() in let final dynamic #t2 = #t1.x = 3 in #t1;
+static field dynamic f = 2.+(3);
+static field dynamic g = 3.unary-();
+static field dynamic h = new self::A::•().+(3);
+static field dynamic i = new self::A::•().unary-();
+static field dynamic j = null as self::B;
+static method test1() → dynamic {
+  self::a = "hi";
+  self::a = new self::B::•(3);
+  self::b = "hi";
+  self::b = new self::B::•(3);
+  self::c1 = <dynamic>[];
+  self::c1 = <dynamic, dynamic>{};
+  self::c2 = <dynamic>[];
+  self::c2 = <dynamic, dynamic>{};
+  self::d = <dynamic, dynamic>{};
+  self::d = 3;
+  self::e = new self::A::•();
+  self::e = <dynamic, dynamic>{};
+  self::f = 3;
+  self::f = false;
+  self::g = 1;
+  self::g = false;
+  self::h = false;
+  self::h = new self::B::•("b");
+  self::i = false;
+  self::j = new self::B::•("b");
+  self::j = false;
+  self::j = <dynamic>[];
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
new file mode 100644
index 0000000..3038e65
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart.strong.transformed.expect
@@ -0,0 +1,94 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → self::B
+    return null;
+}
+class B extends self::A {
+  constructor •(dynamic ignore) → void
+    : super self::A::•()
+    ;
+}
+static field self::A a = new self::A::•();
+static field self::B b = new self::B::•(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#x, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+static field core::List<dynamic> c1 = <dynamic>[throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#x, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))];
+static field core::List<dynamic> c2 = const <dynamic>[];
+static field core::Map<dynamic, dynamic> d = <dynamic, dynamic>{"a": "b"};
+static field self::A e = let final self::A #t1 = new self::A::•() in let final core::int #t2 = #t1.{self::A::x} = 3 in #t1;
+static field core::int f = 2.{core::num::+}(3);
+static field core::int g = 3.{core::int::unary-}();
+static field self::B h = new self::A::•().{self::A::+}(3);
+static field dynamic i = let final self::A #t3 = new self::A::•() in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:34:79: Error: The method 'unary-' isn't defined for the class 'test::A'.
+Try correcting the name to the name of an existing method, or defining a method named 'unary-'.
+var /*@topType=dynamic*/ i = /*error:UNDEFINED_OPERATOR,info:DYNAMIC_INVOKE*/ -new A();
+                                                                              ^";
+static field self::B j = null as self::B;
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:19:61: Error: Getter not found: 'x'.
+var /*@topType=B*/ b = new B(/*error:UNDEFINED_IDENTIFIER*/ x); // allocations
+                                                            ^", "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:21:34: Error: Getter not found: 'x'.
+  /*error:UNDEFINED_IDENTIFIER*/ x
+                                 ^"]/* from null */;
+static method test1() → dynamic {
+  self::a = let final core::String #t4 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:38:36: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'test::A'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A'.
+  a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                   ^";
+  self::a = new self::B::•(3);
+  self::b = let final core::String #t5 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:40:36: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'test::B'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::B'.
+  b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                   ^";
+  self::b = new self::B::•(3);
+  self::c1 = <dynamic>[];
+  self::c1 = let final core::Map<dynamic, dynamic> #t6 = <dynamic, dynamic>{} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:43:68: Error: A value of type 'dart.core::Map<dynamic, dynamic>' can't be assigned to a variable of type 'dart.core::List<dynamic>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::List<dynamic>'.
+  c1 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
+                                                                   ^";
+  self::c2 = <dynamic>[];
+  self::c2 = let final core::Map<dynamic, dynamic> #t7 = <dynamic, dynamic>{} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:45:68: Error: A value of type 'dart.core::Map<dynamic, dynamic>' can't be assigned to a variable of type 'dart.core::List<dynamic>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::List<dynamic>'.
+  c2 = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
+                                                                   ^";
+  self::d = <dynamic, dynamic>{};
+  self::d = let final core::int #t8 = 3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:47:36: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::Map<dynamic, dynamic>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::Map<dynamic, dynamic>'.
+  d = /*error:INVALID_ASSIGNMENT*/ 3;
+                                   ^";
+  self::e = new self::A::•();
+  self::e = let final core::Map<dynamic, dynamic> #t9 = <dynamic, dynamic>{} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:49:67: Error: A value of type 'dart.core::Map<dynamic, dynamic>' can't be assigned to a variable of type 'test::A'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A'.
+  e = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic, dynamic*/ {};
+                                                                  ^";
+  self::f = 3;
+  self::f = let final core::bool #t10 = false in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:51:36: Error: A value of type 'dart.core::bool' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  f = /*error:INVALID_ASSIGNMENT*/ false;
+                                   ^";
+  self::g = 1;
+  self::g = let final core::bool #t11 = false in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:53:36: Error: A value of type 'dart.core::bool' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  g = /*error:INVALID_ASSIGNMENT*/ false;
+                                   ^";
+  self::h = let final core::bool #t12 = false in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:54:36: Error: A value of type 'dart.core::bool' can't be assigned to a variable of type 'test::B'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::B'.
+  h = /*error:INVALID_ASSIGNMENT*/ false;
+                                   ^";
+  self::h = new self::B::•("b");
+  self::i = false;
+  self::j = new self::B::•("b");
+  self::j = let final core::bool #t13 = false in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:58:36: Error: A value of type 'dart.core::bool' can't be assigned to a variable of type 'test::B'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::B'.
+  j = /*error:INVALID_ASSIGNMENT*/ false;
+                                   ^";
+  self::j = let final core::List<dynamic> #t14 = <dynamic>[] in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_complex_expressions_if_outer_most_value_is_precise.dart:59:58: Error: A value of type 'dart.core::List<dynamic>' can't be assigned to a variable of type 'test::B'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::B'.
+  j = /*error:INVALID_ASSIGNMENT*/ /*@typeArgs=dynamic*/ [];
+                                                         ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.direct.transformed.expect
new file mode 100644
index 0000000..a7633e5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A {
+  field dynamic x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic {
+  core::String y = new self::B::•().x;
+  core::int z = new self::B::•().x;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.strong.transformed.expect
new file mode 100644
index 0000000..b8aaf798
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A {
+  field dynamic x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic {
+  core::String y = new self::B::•().{self::B::x} as{TypeError} core::String;
+  core::int z = new self::B::•().{self::B::x} as{TypeError} core::int;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.direct.transformed.expect
new file mode 100644
index 0000000..51c4c9f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A {
+  final field dynamic x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic {
+  core::String y = new self::B::•().x;
+  core::int z = new self::B::•().x;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.strong.transformed.expect
new file mode 100644
index 0000000..bbcf3a6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_rhs_only_if_it_wont_conflict_with_overridden_fields2.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A {
+  final field dynamic x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo() → dynamic {
+  core::String y = new self::B::•().{self::B::x} as{TypeError} core::String;
+  core::int z = new self::B::•().{self::B::x} as{TypeError} core::int;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.direct.transformed.expect
new file mode 100644
index 0000000..bb04180
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
+
+static field dynamic y = inf::x;
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf::x;
+  t = self::y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect
new file mode 100644
index 0000000..a5f2279
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart" as inf;
+
+static field core::int y = inf::x;
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf::x;
+  t = self::y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.direct.transformed.expect
new file mode 100644
index 0000000..9dcf842
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+
+class B extends core::Object {
+  static field dynamic y = inf::A::x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf::A::x;
+  t = self::B::y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect
new file mode 100644
index 0000000..3480785
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart" as inf;
+
+class B extends core::Object {
+  static field core::int y = inf::A::x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  core::int t = 3;
+  t = inf::A::x;
+  t = self::B::y;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.direct.transformed.expect
new file mode 100644
index 0000000..d731588
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field dynamic x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect
new file mode 100644
index 0000000..cb3b662
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on2_a.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.direct.transformed.expect
new file mode 100644
index 0000000..c198bc7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.direct.transformed.expect
@@ -0,0 +1,5 @@
+library;
+import self as self;
+
+static field dynamic x = 2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect
new file mode 100644
index 0000000..bcc0a02
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_cycle_libs_when_flag_is_on_a.dart.strong.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static field core::int x = 2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.direct.transformed.expect
new file mode 100644
index 0000000..7471980
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "./infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
+
+static field dynamic y = inf::x;
+static method test1() → dynamic {
+  inf::x = "hi";
+  self::y = "hi";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
new file mode 100644
index 0000000..db59943
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "./infer_from_variables_in_non_cycle_imports_with_flag_a.dart" as inf;
+import "dart:core" as core;
+
+static field core::int y = inf::x;
+static method test1() → dynamic {
+  inf::x = let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:13:36: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                   ^";
+  self::y = let final core::String #t2 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag.dart:14:36: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  y = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                   ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.direct.transformed.expect
new file mode 100644
index 0000000..598ac7e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
+
+class B extends core::Object {
+  static field dynamic y = inf::A::x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  inf::A::x = "hi";
+  self::B::y = "hi";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
new file mode 100644
index 0000000..dbef01c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_from_variables_in_non_cycle_imports_with_flag2_a.dart" as inf;
+
+class B extends core::Object {
+  static field core::int y = inf::A::x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test1() → dynamic {
+  inf::A::x = let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:15:38: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  A.x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                     ^";
+  self::B::y = let final core::String #t2 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2.dart:16:38: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  B.y = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                     ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.direct.transformed.expect
new file mode 100644
index 0000000..d731588
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field dynamic x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.strong.transformed.expect
new file mode 100644
index 0000000..cb3b662
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag2_a.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.direct.transformed.expect
new file mode 100644
index 0000000..a80145a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static field dynamic x = 2;
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.strong.transformed.expect
new file mode 100644
index 0000000..a76a1e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_from_variables_in_non_cycle_imports_with_flag_a.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static field core::int x = 2;
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.direct.transformed.expect
new file mode 100644
index 0000000..79ae48f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(core::int a, {core::String b = null, self::C::m::T c = null}) → self::C::m::T
+    return null;
+}
+static method main() → dynamic {
+  dynamic y = new self::C::•().m(1, b: "bbb", c: 2.0);
+}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.strong.transformed.expect
new file mode 100644
index 0000000..3e03634
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_named.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(core::int a, {core::String b = null, self::C::m::T c = null}) → self::C::m::T
+    return null;
+}
+static method main() → dynamic {
+  core::double y = new self::C::•().{self::C::m}<core::double>(1, b: "bbb", c: 2.0);
+}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.direct.transformed.expect
new file mode 100644
index 0000000..b3f2fc0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(core::int a, [self::C::m::T b = null]) → self::C::m::T
+    return null;
+}
+static method main() → dynamic {
+  dynamic y = new self::C::•().m(1, 2.0);
+}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.strong.transformed.expect
new file mode 100644
index 0000000..7f57027
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(core::int a, [self::C::m::T b = null]) → self::C::m::T
+    return null;
+}
+static method main() → dynamic {
+  core::double y = new self::C::•().{self::C::m}<core::double>(1, 2.0);
+}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.direct.transformed.expect
new file mode 100644
index 0000000..c4ff57c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(core::int a, [core::String b = null, self::C::m::T c = null]) → self::C::m::T
+    return null;
+}
+static method main() → dynamic {
+  dynamic y = new self::C::•().m(1, "bbb", 2.0);
+}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.strong.transformed.expect
new file mode 100644
index 0000000..4b84fa0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_positional2.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(core::int a, [core::String b = null, self::C::m::T c = null]) → self::C::m::T
+    return null;
+}
+static method main() → dynamic {
+  core::double y = new self::C::•().{self::C::m}<core::double>(1, "bbb", 2.0);
+}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.direct.transformed.expect
new file mode 100644
index 0000000..c9998b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(self::C::m::T x) → self::C::m::T
+    return x;
+}
+static method main() → dynamic {
+  dynamic y = new self::C::•().m(42);
+}
diff --git a/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.strong.transformed.expect
new file mode 100644
index 0000000..1d672d3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_generic_method_type_required.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m<T extends core::Object>(self::C::m::T x) → self::C::m::T
+    return x;
+}
+static method main() → dynamic {
+  core::int y = new self::C::•().{self::C::m}<core::int>(42);
+}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..1ee8980
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::double value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract get x() → dynamic;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..a3c7415
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_cross_to_setter.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::double value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract get x() → core::double;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.direct.transformed.expect
new file mode 100644
index 0000000..90c449e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.direct.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → dynamic
+    return self::f();
+}
+abstract class B extends core::Object implements self::C {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → dynamic;
+}
+abstract class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+static method f() → dynamic
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.strong.transformed.expect
new file mode 100644
index 0000000..643f30d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_getter_from_later_inferred_getter.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return self::f() as{TypeError} core::int;
+}
+abstract class B extends core::Object implements self::C {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+abstract class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+}
+static method f() → dynamic
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.direct.transformed.expect
new file mode 100644
index 0000000..3ae0ee0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.direct.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Resource extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Folder extends self::Resource {
+  synthetic constructor •() → void
+    : super self::Resource::•()
+    ;
+}
+class Foo<T extends core::Object> extends core::Object {
+  constructor •(self::Foo::T t) → void
+    : super core::Object::•()
+    ;
+}
+static method getResource(core::String str) → self::Resource
+  return null;
+static method main() → dynamic {
+  dynamic map = <core::String, core::List<self::Folder>>{"pkgA": <dynamic>[self::getResource("/pkgA/lib/")], "pkgB": <dynamic>[self::getResource("/pkgB/lib/")]};
+  dynamic list = <core::Map<core::String, self::Folder>>[<dynamic, dynamic>{"pkgA": self::getResource("/pkgA/lib/")}, <dynamic, dynamic>{"pkgB": self::getResource("/pkgB/lib/")}];
+  dynamic foo = new self::Foo::•<core::List<self::Folder>>(<dynamic>[self::getResource("/pkgA/lib/")]);
+}
diff --git a/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.strong.transformed.expect
new file mode 100644
index 0000000..61a99de
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_list_literal_nested_in_map_literal.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Resource extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Folder extends self::Resource {
+  synthetic constructor •() → void
+    : super self::Resource::•()
+    ;
+}
+class Foo<T extends core::Object> extends core::Object {
+  constructor •(self::Foo::T t) → void
+    : super core::Object::•()
+    ;
+}
+static method getResource(core::String str) → self::Resource
+  return null;
+static method main() → dynamic {
+  core::Map<core::String, core::List<self::Folder>> map = <core::String, core::List<self::Folder>>{"pkgA": <self::Folder>[self::getResource("/pkgA/lib/") as{TypeError} self::Folder], "pkgB": <self::Folder>[self::getResource("/pkgB/lib/") as{TypeError} self::Folder]};
+  core::List<core::Map<core::String, self::Folder>> list = <core::Map<core::String, self::Folder>>[<core::String, self::Folder>{"pkgA": self::getResource("/pkgA/lib/") as{TypeError} self::Folder}, <core::String, self::Folder>{"pkgB": self::getResource("/pkgB/lib/") as{TypeError} self::Folder}];
+  self::Foo<core::List<self::Folder>> foo = new self::Foo::•<core::List<self::Folder>>(<self::Folder>[self::getResource("/pkgA/lib/") as{TypeError} self::Folder]);
+}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
new file mode 100644
index 0000000..b71b402
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Previous use of 'g'.
+  /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
+                                                                         ^"]/* from null */;
+static method test() → dynamic {
+  function f() → dynamic
+    return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+  invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+  g() => 0;
+  ^";
+  dynamic v = f;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
new file mode 100644
index 0000000..6343ea9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Method not found: 'g'.
+  /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
+                                                                         ^", "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:9:74: Error: Previous use of 'g'.
+  /*@returnType=dynamic*/ f() => /*error:REFERENCED_BEFORE_DECLARATION*/ g();
+                                                                         ^"]/* from null */;
+static method test() → dynamic {
+  function f() → dynamic
+    return throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#g, 32, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+  invalid-expression "pkg/front_end/testcases/inference/infer_local_function_referenced_before_declaration.dart:14:3: Error: Can't declare 'g' because it was already used in this scope.
+  g() => 0;
+  ^";
+  () → dynamic v = f;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..95cdc12
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.direct.transformed.expect
@@ -0,0 +1,129 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  function f0() → dynamic
+    return 42;
+  function f1() → dynamic /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = 42;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+  function f2() → dynamic {
+    return 42;
+  }
+  function f3() → dynamic /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          :return_value = 42;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+  function f4() → dynamic /* originally sync* */ {
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :sync_op(core::_SyncIterator<dynamic> :iterator) → core::bool yielding {
+      {
+        {
+          :iterator.{core::_SyncIterator::_current} = 42;
+          [yield] true;
+        }
+      }
+      return false;
+    }
+    return new core::_SyncIterable::•<dynamic>(:sync_op);
+  }
+  function f5() → dynamic /* originally async* */ {
+    asy::_AsyncStarStreamController<dynamic> :controller;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try
+        try {
+          #L3:
+          {
+            if(:controller.{asy::_AsyncStarStreamController::add}(42))
+              return null;
+            else
+              [yield] null;
+          }
+          return;
+        }
+        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+          :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+        }
+      finally {
+        :controller.{asy::_AsyncStarStreamController::close}();
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :controller = new asy::_AsyncStarStreamController::•<dynamic>(:async_op);
+    return :controller.{asy::_AsyncStarStreamController::stream};
+  }
+  function f6() → core::num
+    return 42;
+  function f7() → dynamic
+    return f7.call();
+  function f8() → dynamic
+    return f5.call();
+  dynamic v0 = f0;
+  dynamic v1 = f1;
+  dynamic v2 = f2;
+  dynamic v3 = f3;
+  dynamic v4 = f4;
+  dynamic v5 = f5;
+  dynamic v6 = f6;
+  dynamic v7 = f7;
+  dynamic v8 = f8;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..5e738e7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
@@ -0,0 +1,129 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+static method test() → dynamic {
+  function f0() → core::int
+    return 42;
+  function f1() → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = 42;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+  function f2() → core::int {
+    return 42;
+  }
+  function f3() → asy::Future<core::int> /* originally async */ {
+    final asy::Completer<core::int> :completer = asy::Completer::sync<core::int>();
+    asy::FutureOr<core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L2:
+        {
+          :return_value = 42;
+          break #L2;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+  function f4() → core::Iterable<core::int> /* originally sync* */ {
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :sync_op(core::_SyncIterator<core::int> :iterator) → core::bool yielding {
+      {
+        {
+          :iterator.{core::_SyncIterator::_current} = 42;
+          [yield] true;
+        }
+      }
+      return false;
+    }
+    return new core::_SyncIterable::•<core::int>(:sync_op);
+  }
+  function f5() → asy::Stream<core::int> /* originally async* */ {
+    asy::_AsyncStarStreamController<core::int> :controller;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try
+        try {
+          #L3:
+          {
+            if(:controller.{asy::_AsyncStarStreamController::add}(42))
+              return null;
+            else
+              [yield] null;
+          }
+          return;
+        }
+        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+          :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+        }
+      finally {
+        :controller.{asy::_AsyncStarStreamController::close}();
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :controller = new asy::_AsyncStarStreamController::•<core::int>(:async_op);
+    return :controller.{asy::_AsyncStarStreamController::stream};
+  }
+  function f6() → core::num
+    return 42;
+  function f7() → dynamic
+    return f7.call();
+  function f8() → asy::Stream<core::int>
+    return f5.call();
+  () → core::int v0 = f0;
+  () → asy::Future<core::int> v1 = f1;
+  () → core::int v2 = f2;
+  () → asy::Future<core::int> v3 = f3;
+  () → core::Iterable<core::int> v4 = f4;
+  () → asy::Stream<core::int> v5 = f5;
+  () → core::num v6 = f6;
+  () → dynamic v7 = f7;
+  () → asy::Stream<core::int> v8 = f8;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_method_function_typed.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.direct.transformed.expect
new file mode 100644
index 0000000..cb7e421
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → core::int;
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method x(() → core::int value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract method x(() → dynamic value) → void;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method g(self::B b) → dynamic {
+  b.x(self::f<dynamic>());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_method_function_typed.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.strong.transformed.expect
new file mode 100644
index 0000000..f0e5701
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_function_typed.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → core::int;
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method x(() → core::int value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract method x(() → dynamic value) → void;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method g(self::B b) → dynamic {
+  b.{self::B::x}(self::f<() → dynamic>());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_method_missing_params.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.direct.transformed.expect
new file mode 100644
index 0000000..80a5e2b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_method_missing_params.dart.direct.transformed.expect
@@ -0,0 +1,29 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(core::int x, core::int y) → core::int;
+  abstract method g(core::int x, [core::int y = null]) → core::int;
+  abstract method h(core::int x, {core::int y = null}) → core::int;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(core::int x) → core::int;
+  abstract method g(core::int x) → core::int;
+  abstract method h(core::int x) → core::int;
+}
+abstract class C extends core::Object implements self::A, self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(dynamic x, dynamic y) → dynamic;
+  abstract method g(dynamic x, [dynamic y = null]) → dynamic;
+  abstract method h(dynamic x, {dynamic y = null}) → dynamic;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..1ae97da
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  set foo(dynamic x) → dynamic {}
+}
+class D extends core::Object {
+  field core::int foo = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..df2c93c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_field.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  set foo(core::int x) → void {}
+}
+class D extends core::Object {
+  field core::int foo = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..30425c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  set foo(dynamic x) → dynamic {}
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set foo(core::int x) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..a6997bd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_parameter_type_setter_from_setter.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  set foo(core::int x) → void {}
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set foo(core::int x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.direct.transformed.expect
new file mode 100644
index 0000000..0af17a3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+
+static field dynamic a_not = !true;
+static field dynamic a_complement = 1.~();
+static field dynamic a_negate = 1.unary-();
+static method main() → dynamic {
+  self::a_not;
+  self::a_complement;
+  self::a_negate;
+}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.strong.transformed.expect
new file mode 100644
index 0000000..6137c7c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::bool a_not = !true;
+static field core::int a_complement = 1.{core::int::~}();
+static field core::int a_negate = 1.{core::int::unary-}();
+static method main() → dynamic {
+  self::a_not;
+  self::a_complement;
+  self::a_negate;
+}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.direct.transformed.expect
new file mode 100644
index 0000000..2d0c29c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  operator ~() → core::int
+    return 1;
+  operator unary-() → core::double
+    return 2.0;
+}
+static field dynamic a = new self::A::•();
+static field dynamic v_complement = self::a.~();
+static field dynamic v_negate = self::a.unary-();
+static method main() → dynamic {
+  self::a;
+  self::v_complement;
+  self::v_negate;
+}
diff --git a/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.strong.transformed.expect
new file mode 100644
index 0000000..1fbb9c3c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_prefix_expression_custom.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  operator ~() → core::int
+    return 1;
+  operator unary-() → core::double
+    return 2.0;
+}
+static field self::A a = new self::A::•();
+static field core::int v_complement = self::a.{self::A::~}();
+static field core::double v_negate = self::a.{self::A::unary-}();
+static method main() → dynamic {
+  self::a;
+  self::v_complement;
+  self::v_negate;
+}
diff --git a/pkg/front_end/testcases/inference/infer_rethrow.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_rethrow.dart.direct.transformed.expect
new file mode 100644
index 0000000..5ecaf43
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_rethrow.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+
+static method test(() → dynamic f, () → dynamic g) → dynamic {
+  try {
+    f.call();
+  }
+  on dynamic catch(final dynamic _) {
+    g.call();
+    rethrow;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_rethrow.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_rethrow.dart.strong.transformed.expect
new file mode 100644
index 0000000..5ecaf43
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_rethrow.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+
+static method test(() → dynamic f, () → dynamic g) → dynamic {
+  try {
+    f.call();
+  }
+  on dynamic catch(final dynamic _) {
+    g.call();
+    rethrow;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.direct.transformed.expect
new file mode 100644
index 0000000..8c8697a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method strings() → core::List<core::String> {
+  dynamic stuff = <dynamic>[].expand((dynamic i) → dynamic {
+    return <core::String>[];
+  });
+  return stuff.toList();
+}
+static method main() → dynamic {
+  self::strings();
+}
diff --git a/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.strong.transformed.expect
new file mode 100644
index 0000000..5e931e5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_of_statement_lambda.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method strings() → core::List<core::String> {
+  core::Iterable<core::String> stuff = <dynamic>[].{core::Iterable::expand}<core::String>((dynamic i) → core::List<core::String> {
+    return <core::String>[];
+  });
+  return stuff.{core::Iterable::toList}();
+}
+static method main() → dynamic {
+  self::strings();
+}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..712d6e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static set foo(core::int x) → dynamic {}
+}
+static set bar(core::int x) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..21fab5d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_return_type_for_static_setter.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static set foo(core::int x) → void {}
+}
+static set bar(core::int x) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.direct.transformed.expect
new file mode 100644
index 0000000..bbf939b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::double;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract set x(dynamic value) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.strong.transformed.expect
new file mode 100644
index 0000000..6682a11
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_cross_to_getter.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::double;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract set x(core::double value) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..9c6ea0a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(dynamic value) → void {}
+}
+abstract class B extends core::Object implements self::C {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(dynamic value) → void;
+}
+abstract class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::int value) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..4332580
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_from_later_inferred_setter.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object implements self::B {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int value) → void {}
+}
+abstract class B extends core::Object implements self::C {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::int value) → void;
+}
+abstract class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::int value) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.direct.transformed.expect
new file mode 100644
index 0000000..d15047a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → core::int;
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(() → core::int value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract set x(() → dynamic value) → void;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method g(self::B b) → dynamic {
+  b.x = self::f<dynamic>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.strong.transformed.expect
new file mode 100644
index 0000000..dafd372
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_function_typed.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → core::int;
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(() → core::int value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract set x(() → dynamic value) → void;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method g(self::B b) → dynamic {
+  b.{self::B::x} = self::f<() → dynamic>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.direct.transformed.expect
new file mode 100644
index 0000000..37b4a5d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int i) → void {}
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  set x(core::Object o) → dynamic {}
+}
+static method main() → dynamic {
+  new self::B::•().x = "hello";
+}
diff --git a/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.strong.transformed.expect
new file mode 100644
index 0000000..7024005
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_setter_return_type_only.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int i) → void {}
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  set x(core::Object o) → void {}
+}
+static method main() → dynamic {
+  new self::B::•().{self::B::x} = "hello";
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.direct.transformed.expect
new file mode 100644
index 0000000..7e6a5f6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_statics_transitively_a.dart" as inf;
+
+static final field dynamic m1 = inf::a1;
+static final field dynamic m2 = inf::A::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = self::m1;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect
new file mode 100644
index 0000000..bab2515
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_statics_transitively_a.dart" as inf;
+
+static final field core::int m1 = inf::a1;
+static final field core::int m2 = inf::A::a2;
+static method foo() → dynamic {
+  core::int i;
+  i = self::m1;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.direct.transformed.expect
new file mode 100644
index 0000000..7ebf828
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic x1 = 1;
+static final field dynamic x2 = 1;
+static final field dynamic y1 = self::x1;
+static final field dynamic y2 = self::x2;
+static method foo() → dynamic {
+  core::int i;
+  i = self::y1;
+  i = self::y2;
+}
+static method main() → dynamic {
+  self::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.strong.transformed.expect
new file mode 100644
index 0000000..3a215e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively2.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static const field core::int x1 = 1;
+static final field core::int x2 = 1;
+static final field core::int y1 = self::x1;
+static final field core::int y2 = self::x2;
+static method foo() → dynamic {
+  core::int i;
+  i = self::y1;
+  i = self::y2;
+}
+static method main() → dynamic {
+  self::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.direct.transformed.expect
new file mode 100644
index 0000000..a75b04b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_statics_transitively3_a.dart" as inf;
+
+static const field dynamic t1 = 1;
+static const field dynamic t2 = self::t1;
+static const field dynamic t3 = inf::a1;
+static const field dynamic t4 = inf::a2;
+static const field dynamic t5 = inf::A::a3;
+static const field dynamic t6 = inf::A::a3;
+static method foo() → dynamic {
+  core::int i;
+  i = self::t1;
+  i = self::t2;
+  i = self::t3;
+  i = self::t4;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect
new file mode 100644
index 0000000..497e52d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_statics_transitively3_a.dart" as inf;
+
+static const field core::int t1 = 1;
+static const field core::int t2 = self::t1;
+static const field core::int t3 = inf::a1;
+static const field core::int t4 = inf::a2;
+static const field dynamic t5 = inf::A::a3;
+static const field dynamic t6 = inf::A::a3;
+static method foo() → dynamic {
+  core::int i;
+  i = self::t1;
+  i = self::t2;
+  i = self::t3;
+  i = self::t4;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.direct.transformed.expect
new file mode 100644
index 0000000..b99e0c3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static const field dynamic a3 = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic a1 = 3;
+static const field dynamic a2 = 4;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.strong.transformed.expect
new file mode 100644
index 0000000..766ab62
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively3_a.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static const field dynamic a3 = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field core::int a1 = 3;
+static const field core::int a2 = 4;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.direct.transformed.expect
new file mode 100644
index 0000000..a51abfe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf;
+import "./infer_statics_transitively.dart" as test;
+
+class A extends core::Object {
+  static final field dynamic a2 = inf::b1;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static final field dynamic a1 = test::m2;
+static method main() → dynamic {
+  self::a1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect
new file mode 100644
index 0000000..9e64cd4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_2_a.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf;
+import "./infer_statics_transitively.dart" as test;
+
+class A extends core::Object {
+  static final field core::int a2 = inf::b1;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static final field core::int a1 = test::m2;
+static method main() → dynamic {
+  self::a1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.direct.transformed.expect
new file mode 100644
index 0000000..203f0f2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf;
+import "./infer_statics_transitively.dart" as test;
+
+class A extends core::Object {
+  static final field dynamic a2 = inf::b1;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static final field dynamic a1 = test::m2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect
new file mode 100644
index 0000000..3f00669
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_a.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./infer_statics_transitively_b.dart" as inf;
+import "./infer_statics_transitively.dart" as test;
+
+class A extends core::Object {
+  static final field core::int a2 = inf::b1;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static final field core::int a1 = test::m2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.direct.transformed.expect
new file mode 100644
index 0000000..f95797d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static final field dynamic b1 = 2;
+static method main() → dynamic {
+  self::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.strong.transformed.expect
new file mode 100644
index 0000000..52b1783
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_transitively_b.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static final field core::int b1 = 2;
+static method main() → dynamic {
+  self::b1;
+}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.direct.transformed.expect
new file mode 100644
index 0000000..822e5cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_statics_with_method_invocations_a.dart" as inf;
+
+class T extends core::Object {
+  static final field self::T foo = self::T::m1(self::T::m2(inf::m3("", "")));
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method m1(core::String m) → self::T {
+    return null;
+  }
+  static method m2(dynamic e) → core::String {
+    return "";
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect
new file mode 100644
index 0000000..822e5cf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_statics_with_method_invocations_a.dart" as inf;
+
+class T extends core::Object {
+  static final field self::T foo = self::T::m1(self::T::m2(inf::m3("", "")));
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method m1(core::String m) → self::T {
+    return null;
+  }
+  static method m2(dynamic e) → core::String {
+    return "";
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.direct.transformed.expect
new file mode 100644
index 0000000..60b40d3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method m3(core::String a, core::String b, [dynamic a1 = null, dynamic a2 = null]) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.strong.transformed.expect
new file mode 100644
index 0000000..60b40d3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_statics_with_method_invocations_a.dart.strong.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method m3(core::String a, core::String b, [dynamic a1 = null, dynamic a2 = null]) → dynamic {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_throw.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_throw.dart.direct.transformed.expect
new file mode 100644
index 0000000..3c02469
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+
+static field dynamic t = true;
+static field dynamic a = throw 0;
+static field dynamic b = (throw 0) ? 1 : 2;
+static field dynamic c = self::t ? throw 1 : 2;
+static field dynamic d = self::t ? 1 : throw 2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_throw.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_throw.dart.strong.transformed.expect
new file mode 100644
index 0000000..a5ac554
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::bool t = true;
+static field dynamic a = throw 0;
+static field core::int b = (throw 0) ?{core::int} 1 : 2;
+static field core::int c = self::t ?{core::int} throw 1 : 2;
+static field core::int d = self::t ?{core::int} 1 : throw 2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_throw_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..7e9227c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic x = throw self::f<dynamic>();
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method g() → void {
+  dynamic x = throw self::f<dynamic>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_throw_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..7e9227c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_throw_downwards.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic x = throw self::f<dynamic>();
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method g() → void {
+  dynamic x = throw self::f<dynamic>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.direct.transformed.expect
new file mode 100644
index 0000000..6a398b3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  get x() → dynamic
+    return 3;
+}
+static method foo() → dynamic {
+  core::String y = new self::B::•().x;
+  core::int z = new self::B::•().x;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
new file mode 100644
index 0000000..31064b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  get x() → core::int
+    return 3;
+}
+static method foo() → dynamic {
+  core::String y = let final core::int #t1 = new self::B::•().{self::B::x} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields2.dart:17:69: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
+                                                                    ^";
+  core::int z = new self::B::•().{self::B::x};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.direct.transformed.expect
new file mode 100644
index 0000000..d56d90f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → dynamic
+    return 3;
+}
+static method foo() → dynamic {
+  core::String y = new self::B::•().x;
+  core::int z = new self::B::•().x;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
new file mode 100644
index 0000000..6b2f6fb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 3;
+}
+static method foo() → dynamic {
+  core::String y = let final core::int #t1 = new self::B::•().{self::B::x} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_on_overridden_fields4.dart:17:69: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
+                                                                    ^";
+  core::int z = new self::B::•().{self::B::x};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var.dart.direct.transformed.expect
new file mode 100644
index 0000000..a57d0f1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::int x = 3;
+  x = "hi";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect
new file mode 100644
index 0000000..801f0ec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::int x = 3;
+  x = let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var.dart:10:36: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                   ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.direct.transformed.expect
new file mode 100644
index 0000000..b176583
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static method test2() → dynamic {
+  dynamic x = 3;
+  x = "hi";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect
new file mode 100644
index 0000000..5ff04c6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var2.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test2() → dynamic {
+  core::int x = 3;
+  x = let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var2.dart:10:36: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                   ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..b38889d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 0;
+  field core::int y = null;
+  final field dynamic z = 42;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test1() → dynamic {
+    dynamic a = this.{self::A::x};
+    a = "hi";
+    a = 3;
+    dynamic b = this.{self::A::y};
+    b = "hi";
+    b = 4;
+    dynamic c = this.{self::A::z};
+    c = "hi";
+    c = 4;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..89f651c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 0;
+  field core::int y = null;
+  final field core::int z = 42;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test1() → dynamic {
+    core::int a = this.{self::A::x};
+    a = let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:13:38: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                     ^";
+    a = 3;
+    core::int b = this.{self::A::y};
+    b = let final core::String #t2 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:16:38: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                     ^";
+    b = 4;
+    core::int c = this.{self::A::z};
+    c = let final core::String #t3 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_field.dart:19:38: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+    c = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                     ^";
+    c = 4;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.direct.transformed.expect
new file mode 100644
index 0000000..11b8cab
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int x = 0;
+static field core::int y = 0;
+static final field dynamic z = 42;
+static method test1() → dynamic {
+  dynamic a = self::x;
+  a = "hi";
+  a = 3;
+  dynamic b = self::y;
+  b = "hi";
+  b = 4;
+  dynamic c = self::z;
+  c = "hi";
+  c = 4;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect
new file mode 100644
index 0000000..6fc3b5d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart.strong.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int x = 0;
+static field core::int y = 0;
+static final field core::int z = 42;
+static method test1() → dynamic {
+  core::int a = self::x;
+  a = let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:12:36: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  a = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                   ^";
+  a = 3;
+  core::int b = self::y;
+  b = let final core::String #t2 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:15:36: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  b = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                   ^";
+  b = 4;
+  core::int c = self::z;
+  c = let final core::String #t3 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_on_var_from_top_level.dart:18:36: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  c = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                   ^";
+  c = 4;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.direct.transformed.expect
new file mode 100644
index 0000000..2db852d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.direct.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
+import "dart:core" as core;
+
+class C extends inf::B {
+  synthetic constructor •() → void
+    : super inf::B::•()
+    ;
+  get x() → dynamic
+    return null;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+static method foo() → dynamic {
+  core::int y = new self::C::•().x;
+  core::String z = new self::C::•().x;
+}
+static method main() → dynamic {
+  self::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
new file mode 100644
index 0000000..59c8d66
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart.strong.transformed.expect
@@ -0,0 +1,29 @@
+library test;
+import self as self;
+import "./infer_type_regardless_of_declaration_order_or_cycles_b.dart" as inf;
+import "dart:core" as core;
+
+class C extends inf::B {
+  synthetic constructor •() → void
+    : super inf::B::•()
+    ;
+  get x() → core::int
+    return null;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+static method foo() → dynamic {
+  core::int y = new self::C::•().{self::C::x};
+  core::String z = let final core::int #t1 = new self::C::•().{self::C::x} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles.dart:20:69: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  String z = /*error:INVALID_ASSIGNMENT*/ new C(). /*@target=C::x*/ x;
+                                                                    ^";
+}
+static method main() → dynamic {
+  self::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.direct.transformed.expect
new file mode 100644
index 0000000..cc75323
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
+
+class B extends test::A {
+  synthetic constructor •() → void
+    : super test::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
new file mode 100644
index 0000000..cc75323
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_type_regardless_of_declaration_order_or_cycles_b.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "./infer_type_regardless_of_declaration_order_or_cycles.dart" as test;
+
+class B extends test::A {
+  synthetic constructor •() → void
+    : super test::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.direct.transformed.expect
new file mode 100644
index 0000000..345abe6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic a = <core::int, core::String>{0: "aaa", 1: "bbb"};
+static field dynamic b = <core::double, core::int>{1.1: 1, 2.2: 2};
+static field dynamic c = <core::List<core::int>, core::Map<core::String, core::double>>{};
+static field dynamic d = <core::int, dynamic>{};
+static field dynamic e = <dynamic, core::int>{};
+static field dynamic f = <dynamic, dynamic>{};
+static method main() → dynamic {
+  self::a;
+  self::b;
+  self::c;
+  self::d;
+  self::e;
+  self::f;
+}
diff --git a/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.strong.transformed.expect
new file mode 100644
index 0000000..9542da0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_typed_map_literal.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::Map<core::int, core::String> a = <core::int, core::String>{0: "aaa", 1: "bbb"};
+static field core::Map<core::double, core::int> b = <core::double, core::int>{1.1: 1, 2.2: 2};
+static field core::Map<core::List<core::int>, core::Map<core::String, core::double>> c = <core::List<core::int>, core::Map<core::String, core::double>>{};
+static field core::Map<core::int, dynamic> d = <core::int, dynamic>{};
+static field core::Map<dynamic, core::int> e = <dynamic, core::int>{};
+static field core::Map<dynamic, dynamic> f = <dynamic, dynamic>{};
+static method main() → dynamic {
+  self::a;
+  self::b;
+  self::c;
+  self::d;
+  self::e;
+  self::f;
+}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.direct.transformed.expect
new file mode 100644
index 0000000..cb1b1b6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  final field self::A::T x = null;
+  final field self::A::T w = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → dynamic
+    return 3;
+  get w() → dynamic
+    return "hello";
+}
+static method foo() → dynamic {
+  core::String y = new self::B::•().x;
+  core::int z = new self::B::•().x;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
new file mode 100644
index 0000000..a834f75
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  final field self::A::T x = null;
+  final field self::A::T w = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 3;
+  get w() → core::int
+    return let final core::String #t1 = "hello" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:15:62: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  get /*@topType=int*/ w => /*error:RETURN_OF_INVALID_TYPE*/ \"hello\";
+                                                             ^";
+}
+static method foo() → dynamic {
+  core::String y = let final core::int #t2 = new self::B::•().{self::B::x} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_3.dart:19:69: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  String y = /*error:INVALID_ASSIGNMENT*/ new B(). /*@target=B::x*/ x;
+                                                                    ^";
+  core::int z = new self::B::•().{self::B::x};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.direct.transformed.expect
new file mode 100644
index 0000000..3aa3a9c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  field self::A::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<E extends core::Object> extends self::A<self::B::E> {
+  field self::B::E y = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  get x() → dynamic
+    return this.{self::B::y};
+}
+static method foo() → dynamic {
+  core::int y = new self::B::•<core::String>().x;
+  core::String z = new self::B::•<core::String>().x;
+}
+static method main() → dynamic {
+  self::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
new file mode 100644
index 0000000..19f61cc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart.strong.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::A::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<E extends core::Object> extends self::A<self::B::E> {
+  generic-covariant-impl generic-covariant-interface field self::B::E y = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  get x() → self::B::E
+    return this.{self::B::y};
+}
+static method foo() → dynamic {
+  core::int y = let final core::String #t1 = new self::B::•<core::String>().{self::B::x} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_4.dart:18:74: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  int y = /*error:INVALID_ASSIGNMENT*/ new B<String>(). /*@target=B::x*/ x;
+                                                                         ^";
+  core::String z = new self::B::•<core::String>().{self::B::x};
+}
+static method main() → dynamic {
+  self::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.direct.transformed.expect
new file mode 100644
index 0000000..b9909f6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.direct.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class I<E extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method m(dynamic a, (dynamic, self::I::E) → core::String f) → core::String;
+}
+abstract class A<E extends core::Object> extends core::Object implements self::I<self::A::E> {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method m(dynamic a, (dynamic, self::A::E) → core::String f) → core::String;
+}
+abstract class M extends core::Object {
+  final field core::int y = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<E extends core::Object> extends self::A<self::B::E> implements self::M {
+  const constructor •() → void
+    : super self::A::•()
+    ;
+  get y() → core::int
+    return 0;
+  method m(dynamic a, (dynamic, self::B::E) → dynamic f) → dynamic {}
+}
+static method foo() → dynamic {
+  core::int y = new self::B::•<dynamic>().m(null, null);
+  core::String z = new self::B::•<dynamic>().m(null, null);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
new file mode 100644
index 0000000..183e897
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class I<E extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method m(dynamic a, (dynamic, self::I::E) → core::String f) → core::String;
+}
+abstract class A<E extends core::Object> extends core::Object implements self::I<self::A::E> {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method m(dynamic a, (dynamic, self::A::E) → core::String f) → core::String;
+}
+abstract class M extends core::Object {
+  final field core::int y = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<E extends core::Object> extends self::A<self::B::E> implements self::M {
+  const constructor •() → void
+    : super self::A::•()
+    ;
+  get y() → core::int
+    return 0;
+  method m(dynamic a, (dynamic, self::B::E) → dynamic f) → core::String {}
+}
+static method foo() → dynamic {
+  core::int y = let final core::String #t1 = new self::B::•<dynamic>().{self::B::m}(null, null) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_5.dart:30:26: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      . /*@target=B::m*/ m(null, null);
+                         ^";
+  core::String z = new self::B::•<dynamic>().{self::B::m}(null, null);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.direct.transformed.expect
new file mode 100644
index 0000000..97f9b08
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.direct.transformed.expect
@@ -0,0 +1,30 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
+
+abstract class A<E extends core::Object> extends core::Object implements inf::I<self::A::E> {
+  final field self::A::E value = null;
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class M extends core::Object {
+  final field core::int y = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<E extends core::Object> extends self::A<self::B::E> implements self::M {
+  const constructor •() → void
+    : super self::A::•()
+    ;
+  get y() → core::int
+    return 0;
+  method m(dynamic a, (dynamic, core::int) → dynamic f) → dynamic {}
+}
+static method foo() → dynamic {
+  core::int y = new self::B::•<core::String>().m(null, null).value;
+  core::String z = new self::B::•<core::String>().m(null, null).value;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
new file mode 100644
index 0000000..8c026b3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle_a.dart" as inf;
+
+abstract class A<E extends core::Object> extends core::Object implements inf::I<self::A::E> {
+  final field self::A::E value = null;
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class M extends core::Object {
+  final field core::int y = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<E extends core::Object> extends self::A<self::B::E> implements self::M {
+  const constructor •() → void
+    : super self::A::•()
+    ;
+  get y() → core::int
+    return 0;
+  method m(dynamic a, (dynamic, core::int) → dynamic f) → self::A<self::B::E> {}
+}
+static method foo() → dynamic {
+  core::int y = let final core::String #t1 = new self::B::•<core::String>().{self::B::m}(null, null).{self::A::value} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle.dart:30:30: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      . /*@target=A::value*/ value;
+                             ^";
+  core::String z = new self::B::•<core::String>().{self::B::m}(null, null).{self::A::value};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.direct.transformed.expect
new file mode 100644
index 0000000..b26d0cb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
+
+abstract class I<E extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method m(dynamic a, (dynamic, core::int) → core::String f) → test::A<self::I::E>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
new file mode 100644
index 0000000..b26d0cb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_in_library_cycle_a.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./infer_types_on_generic_instantiations_in_library_cycle.dart" as test;
+
+abstract class I<E extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method m(dynamic a, (dynamic, core::int) → core::String f) → test::A<self::I::E>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.direct.transformed.expect
new file mode 100644
index 0000000..f45b7c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_generic_instantiations_infer.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  final field self::A::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → dynamic
+    return 3;
+}
+static method foo() → dynamic {
+  core::String y = new self::B::•().x;
+  core::int z = new self::B::•().x;
+}
+static method main() → dynamic {
+  self::foo();
+}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.direct.transformed.expect
new file mode 100644
index 0000000..d9c5ceb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.direct.transformed.expect
@@ -0,0 +1,64 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int bar = 42;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar<T extends core::Iterable<core::String>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(self::Bar::T t) → void {
+    for (dynamic i in t) {
+      core::int x = i;
+    }
+  }
+}
+class Baz<T extends core::Object, E extends core::Iterable<self::Baz::T>, S extends self::Baz::E> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(self::Baz::S t) → void {
+    for (dynamic i in t) {
+      core::int x = i;
+      self::Baz::T y = i;
+    }
+  }
+}
+static method test() → dynamic {
+  dynamic list = <self::Foo>[];
+  for (dynamic x in list) {
+    core::String y = x;
+  }
+  for (dynamic x in list) {
+    core::String y = x;
+  }
+  for (core::String x in list) {
+    core::String y = x;
+  }
+  dynamic z;
+  for (final dynamic #t1 in list) {
+    z = #t1;
+    core::String y = z;
+  }
+  core::Iterable<dynamic> iter = list;
+  for (self::Foo x in iter) {
+    dynamic y = x;
+  }
+  dynamic iter2 = list;
+  for (self::Foo x in iter2) {
+    dynamic y = x;
+  }
+  dynamic map = <core::String, self::Foo>{};
+  for (dynamic x in map) {
+    core::String y = x;
+  }
+  for (dynamic x in map.keys) {
+    core::String y = x;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect
new file mode 100644
index 0000000..450c3b5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart.strong.transformed.expect
@@ -0,0 +1,82 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int bar = 42;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar<T extends core::Iterable<core::String>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(generic-covariant-impl generic-covariant-interface self::Bar::T t) → void {
+    for (core::String i in t) {
+      core::int x = let final core::String #t1 = i in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:15:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      int x = /*error:INVALID_ASSIGNMENT*/ i;
+                                           ^";
+    }
+  }
+}
+class Baz<T extends core::Object, E extends core::Iterable<self::Baz::T>, S extends self::Baz::E> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(generic-covariant-impl generic-covariant-interface self::Baz::S t) → void {
+    for (self::Baz::T i in t) {
+      core::int x = let final self::Baz::T #t2 = i in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:23:44: Error: A value of type 'test::Baz::T' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      int x = /*error:INVALID_ASSIGNMENT*/ i;
+                                           ^";
+      self::Baz::T y = i;
+    }
+  }
+}
+static method test() → dynamic {
+  core::List<self::Foo> list = <self::Foo>[];
+  for (self::Foo x in list) {
+    core::String y = let final self::Foo #t3 = x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:32:45: Error: A value of type 'test::Foo' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+    String y = /*error:INVALID_ASSIGNMENT*/ x;
+                                            ^";
+  }
+  for (dynamic x in list) {
+    core::String y = x as{TypeError} core::String;
+  }
+  for (final self::Foo #t4 in list) {
+    core::String x = let final self::Foo #t5 = #t4 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:39:15: Error: A value of type 'test::Foo' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  for (String x in /*error:FOR_IN_OF_INVALID_ELEMENT_TYPE*/ list) {
+              ^";
+    core::String y = x;
+  }
+  dynamic z;
+  for (final self::Foo #t6 in list) {
+    z = #t6;
+    core::String y = z as{TypeError} core::String;
+  }
+  core::Iterable<dynamic> iter = list;
+  for (final dynamic #t7 in iter) {
+    self::Foo x = #t7 as{TypeError} self::Foo;
+    self::Foo y = x;
+  }
+  dynamic iter2 = list;
+  for (final dynamic #t8 in iter2 as{TypeError} core::Iterable<dynamic>) {
+    self::Foo x = #t8 as{TypeError} self::Foo;
+    self::Foo y = x;
+  }
+  core::Map<core::String, self::Foo> map = <core::String, self::Foo>{};
+  for (dynamic x in let final core::Map<core::String, self::Foo> #t9 = map in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop.dart:60:68: Error: A value of type 'dart.core::Map<dart.core::String, test::Foo>' can't be assigned to a variable of type 'dart.core::Iterable<dynamic>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::Iterable<dynamic>'.
+  for (var /*@type=dynamic*/ x in /*error:FOR_IN_OF_INVALID_TYPE*/ map) {
+                                                                   ^") {
+    core::String y = x as{TypeError} core::String;
+  }
+  for (core::String x in map.{core::Map::keys}) {
+    core::String y = x;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.direct.transformed.expect
new file mode 100644
index 0000000..bfda42e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.direct.transformed.expect
@@ -0,0 +1,309 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class Foo extends core::Object {
+  field core::int bar = 42;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar<T extends asy::Stream<core::String>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(self::Bar::T t) → dynamic /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    dynamic :exception0;
+    dynamic :stack_trace0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          {
+            asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(t);
+            try
+              #L2:
+              while (true) {
+                [yield] let dynamic #t1 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+                if(:result) {
+                  dynamic i = :for-iterator.{asy::_StreamIterator::current};
+                  {
+                    core::int x = i;
+                  }
+                }
+                else
+                  break #L2;
+              }
+            finally
+              if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+                [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+                :result;
+              }
+          }
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+}
+class Baz<T extends core::Object, E extends asy::Stream<self::Baz::T>, S extends self::Baz::E> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(self::Baz::S t) → dynamic /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    dynamic :exception0;
+    dynamic :stack_trace0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          {
+            asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(t);
+            try
+              #L4:
+              while (true) {
+                [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+                if(:result) {
+                  dynamic i = :for-iterator.{asy::_StreamIterator::current};
+                  {
+                    core::int x = i;
+                    self::Baz::T y = i;
+                  }
+                }
+                else
+                  break #L4;
+              }
+            finally
+              if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+                [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+                :result;
+              }
+          }
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+}
+abstract class MyStream<T extends core::Object> extends asy::Stream<self::MyStream::T> {
+  static factory •<T extends core::Object>() → self::MyStream<self::MyStream::•::T>
+    return null;
+}
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L5:
+      {
+        dynamic myStream = self::MyStream::•<self::Foo>();
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(myStream);
+          try
+            #L6:
+            while (true) {
+              [yield] let dynamic #t5 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  core::String y = x;
+                }
+              }
+              else
+                break #L6;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(myStream);
+          try
+            #L7:
+            while (true) {
+              [yield] let dynamic #t7 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  core::String y = x;
+                }
+              }
+              else
+                break #L7;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t8 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<core::String> :for-iterator = new asy::_StreamIterator::•<core::String>(myStream);
+          try
+            #L8:
+            while (true) {
+              [yield] let dynamic #t9 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                core::String x = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  core::String y = x;
+                }
+              }
+              else
+                break #L8;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t10 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        dynamic z;
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(myStream);
+          try
+            #L9:
+            while (true) {
+              [yield] let dynamic #t11 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t12 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  z = #t12;
+                  core::String y = z;
+                }
+              }
+              else
+                break #L9;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t13 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        asy::Stream<dynamic> stream = myStream;
+        {
+          asy::_StreamIterator<self::Foo> :for-iterator = new asy::_StreamIterator::•<self::Foo>(stream);
+          try
+            #L10:
+            while (true) {
+              [yield] let dynamic #t14 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                self::Foo x = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  dynamic y = x;
+                }
+              }
+              else
+                break #L10;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t15 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        dynamic stream2 = myStream;
+        {
+          asy::_StreamIterator<self::Foo> :for-iterator = new asy::_StreamIterator::•<self::Foo>(stream2);
+          try
+            #L11:
+            while (true) {
+              [yield] let dynamic #t16 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                self::Foo x = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  dynamic y = x;
+                }
+              }
+              else
+                break #L11;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t17 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        dynamic map = <core::String, self::Foo>{};
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(map);
+          try
+            #L12:
+            while (true) {
+              [yield] let dynamic #t18 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  core::String y = x;
+                }
+              }
+              else
+                break #L12;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t19 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
new file mode 100644
index 0000000..86d23fa
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
@@ -0,0 +1,327 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class Foo extends core::Object {
+  field core::int bar = 42;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar<T extends asy::Stream<core::String>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(generic-covariant-impl generic-covariant-interface self::Bar::T t) → dynamic /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    dynamic :exception0;
+    dynamic :stack_trace0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          {
+            asy::_StreamIterator<core::String> :for-iterator = new asy::_StreamIterator::•<core::String>(t);
+            try
+              #L2:
+              while (true) {
+                [yield] let dynamic #t1 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+                if(:result) {
+                  core::String i = :for-iterator.{asy::_StreamIterator::current};
+                  {
+                    core::int x = let final core::String #t2 = i in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:17:44: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      int x = /*error:INVALID_ASSIGNMENT*/ i;
+                                           ^";
+                  }
+                }
+                else
+                  break #L2;
+              }
+            finally
+              if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+                [yield] let dynamic #t3 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+                :result;
+              }
+          }
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+}
+class Baz<T extends core::Object, E extends asy::Stream<self::Baz::T>, S extends self::Baz::E> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(generic-covariant-impl generic-covariant-interface self::Baz::S t) → dynamic /* originally async */ {
+    final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+    asy::FutureOr<dynamic> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    dynamic :exception0;
+    dynamic :stack_trace0;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L3:
+        {
+          {
+            asy::_StreamIterator<self::Baz::T> :for-iterator = new asy::_StreamIterator::•<self::Baz::T>(t);
+            try
+              #L4:
+              while (true) {
+                [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+                if(:result) {
+                  self::Baz::T i = :for-iterator.{asy::_StreamIterator::current};
+                  {
+                    core::int x = let final self::Baz::T #t5 = i in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:25:44: Error: A value of type 'test::Baz::T' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      int x = /*error:INVALID_ASSIGNMENT*/ i;
+                                           ^";
+                    self::Baz::T y = i;
+                  }
+                }
+                else
+                  break #L4;
+              }
+            finally
+              if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+                [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+                :result;
+              }
+          }
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+}
+abstract class MyStream<T extends core::Object> extends asy::Stream<self::MyStream::T> {
+  static factory •<T extends core::Object>() → self::MyStream<self::MyStream::•::T>
+    return null;
+}
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L5:
+      {
+        self::MyStream<self::Foo> myStream = self::MyStream::•<self::Foo>();
+        {
+          asy::_StreamIterator<self::Foo> :for-iterator = new asy::_StreamIterator::•<self::Foo>(myStream);
+          try
+            #L6:
+            while (true) {
+              [yield] let dynamic #t7 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                self::Foo x = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  core::String y = let final self::Foo #t8 = x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:38:45: Error: A value of type 'test::Foo' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+    String y = /*error:INVALID_ASSIGNMENT*/ x;
+                                            ^";
+                }
+              }
+              else
+                break #L6;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t9 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(myStream);
+          try
+            #L7:
+            while (true) {
+              [yield] let dynamic #t10 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  core::String y = x as{TypeError} core::String;
+                }
+              }
+              else
+                break #L7;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t11 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        {
+          asy::_StreamIterator<self::Foo> :for-iterator = new asy::_StreamIterator::•<self::Foo>(myStream);
+          try
+            #L8:
+            while (true) {
+              [yield] let dynamic #t12 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final self::Foo #t13 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  core::String x = let final self::Foo #t14 = #t13 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:45:21: Error: A value of type 'test::Foo' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  await for (String x in /*error:FOR_IN_OF_INVALID_ELEMENT_TYPE*/ myStream) {
+                    ^";
+                  core::String y = x;
+                }
+              }
+              else
+                break #L8;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t15 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        dynamic z;
+        {
+          asy::_StreamIterator<self::Foo> :for-iterator = new asy::_StreamIterator::•<self::Foo>(myStream);
+          try
+            #L9:
+            while (true) {
+              [yield] let dynamic #t16 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final self::Foo #t17 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  z = #t17;
+                  core::String y = z as{TypeError} core::String;
+                }
+              }
+              else
+                break #L9;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t18 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        asy::Stream<dynamic> stream = myStream;
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(stream);
+          try
+            #L10:
+            while (true) {
+              [yield] let dynamic #t19 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t20 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  self::Foo x = #t20 as{TypeError} self::Foo;
+                  self::Foo y = x;
+                }
+              }
+              else
+                break #L10;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t21 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        dynamic stream2 = myStream;
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(stream2 as{TypeError} asy::Stream<dynamic>);
+          try
+            #L11:
+            while (true) {
+              [yield] let dynamic #t22 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t23 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  self::Foo x = #t23 as{TypeError} self::Foo;
+                  self::Foo y = x;
+                }
+              }
+              else
+                break #L11;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t24 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        core::Map<core::String, self::Foo> map = <core::String, self::Foo>{};
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(let final core::Map<core::String, self::Foo> #t25 = map in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:66:74: Error: A value of type 'dart.core::Map<dart.core::String, test::Foo>' can't be assigned to a variable of type 'dart.async::Stream<dynamic>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.async::Stream<dynamic>'.
+  await for (var /*@type=dynamic*/ x in /*error:FOR_IN_OF_INVALID_TYPE*/ map) {
+                                                                         ^");
+          try
+            #L12:
+            while (true) {
+              [yield] let dynamic #t26 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                dynamic x = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  core::String y = x as{TypeError} core::String;
+                }
+              }
+              else
+                break #L12;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t27 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.direct.transformed.expect
new file mode 100644
index 0000000..0445457
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  for (dynamic i = 0; i.<(10); i = i.+(1)) {
+    core::int j = i.+(1);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..e3d4755
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_loop_with_inference.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → dynamic {
+  for (core::int i = 0; i.{core::num::<}(10); i = i.{core::num::+}(1)) {
+    core::int j = i.{core::num::+}(1);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.direct.transformed.expect
new file mode 100644
index 0000000..cfdd2e4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static method f() → void {}
+static method g() → void {
+  dynamic x = self::f();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.strong.transformed.expect
new file mode 100644
index 0000000..f8773b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_use_of_void_local.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static method f() → void {}
+static method g() → void {
+  void x = self::f();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/infer_variable_void.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/infer_variable_void.dart.direct.transformed.expect
new file mode 100644
index 0000000..1d9c92b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_variable_void.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static field dynamic x = self::f();
+static method f() → void {}
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/infer_variable_void.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_variable_void.dart.strong.transformed.expect
new file mode 100644
index 0000000..3bfd2e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/infer_variable_void.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static field void x = self::f();
+static method f() → void {}
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.direct.transformed.expect
new file mode 100644
index 0000000..b05a44c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic x = 1;
+  constructor •([dynamic x = "1"]) → void
+    : self::Foo::x = x, super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect
new file mode 100644
index 0000000..ecee299
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int x = 1;
+  constructor •([core::int x = let final core::String #t1 = "1" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/inferred_initializing_formal_checks_default_value.dart:10:46: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  Foo([this.x = /*error:INVALID_ASSIGNMENT*/ \"1\"]);
+                                             ^"]) → void
+    : self::Foo::x = x, super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.direct.transformed.expect
new file mode 100644
index 0000000..6e0646b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field dynamic x = "x";
+  field dynamic y = <dynamic, dynamic>{"a": <dynamic, dynamic>{"b": "c"}, "d": <dynamic, dynamic>{"e": self::C::x}};
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.strong.transformed.expect
new file mode 100644
index 0000000..9830b33
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_static_field_complex.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::String x = "x";
+  field core::Map<core::String, core::Map<core::String, core::String>> y = <core::String, core::Map<core::String, core::String>>{"a": <core::String, core::String>{"b": "c"}, "d": <core::String, core::String>{"e": self::C::x}};
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.direct.transformed.expect
new file mode 100644
index 0000000..92326d3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic y = self::x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic x = "x";
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.strong.transformed.expect
new file mode 100644
index 0000000..a66e974
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_nonstatic_field_depends_on_top_level_var_simple.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::String y = self::x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::String x = "x";
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.direct.transformed.expect
new file mode 100644
index 0000000..17cd71fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library test;
+import self as self;
+
+static method main() → dynamic {
+  dynamic f = () → dynamic {};
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.transformed.expect
new file mode 100644
index 0000000..21dc5e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  () → core::Null f = () → core::Null {};
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.direct.transformed.expect
new file mode 100644
index 0000000..ea5bd56
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •(() → void func) → void
+    : super core::Object::•() {}
+}
+static method main() → dynamic {
+  dynamic c = new self::C::•(() → dynamic {});
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.transformed.expect
new file mode 100644
index 0000000..8b9f2be
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_block_closure_no_args_no_return_void_context.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •(() → void func) → void
+    : super core::Object::•() {}
+}
+static method main() → dynamic {
+  self::C c = new self::C::•(() → core::Null {});
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.direct.transformed.expect
new file mode 100644
index 0000000..49bd0c9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int a = null;
+  field core::List<core::int> b = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → void {}
+}
+static field dynamic v = let final dynamic #t1 = new self::A::•() in let final dynamic #t2 = #t1.a = 1 in let final dynamic #t3 = #t1.b.add(2) in let final dynamic #t4 = #t1.m() in #t1;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.transformed.expect
new file mode 100644
index 0000000..3912678
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_cascade.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int a = null;
+  field core::List<core::int> b = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → void {}
+}
+static field self::A v = let final self::A #t1 = new self::A::•() in let final core::int #t2 = #t1.{self::A::a} = 1 in let final void #t3 = #t1.{self::A::b}.{core::List::add}(2) in let final void #t4 = #t1.{self::A::m}() in #t1;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.direct.transformed.expect
new file mode 100644
index 0000000..6e12e92
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator *(self::C other) → core::bool
+    return true;
+}
+static field self::C c = new self::C::•();
+static field dynamic x = self::c.*(self::c);
+static method main() → dynamic {
+  self::c;
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.strong.transformed.expect
new file mode 100644
index 0000000..e3f488f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator *(self::C other) → core::bool
+    return true;
+}
+static field self::C c = new self::C::•();
+static field core::bool x = self::c.{self::C::*}(self::c);
+static method main() → dynamic {
+  self::c;
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.direct.transformed.expect
new file mode 100644
index 0000000..d1ae550
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator *(self::C other) → core::bool
+    return true;
+}
+abstract class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C c;
+static field dynamic x = self::c.*(self::c);
+static method main() → dynamic {
+  self::c;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.strong.transformed.expect
new file mode 100644
index 0000000..f4bad7c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_binary_op_via_interface.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator *(self::C other) → core::bool
+    return true;
+}
+abstract class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C c;
+static field core::bool x = self::c.{self::I::*}(self::c);
+static method main() → dynamic {
+  self::c;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.direct.transformed.expect
new file mode 100644
index 0000000..f22d693
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int index) → core::bool
+    return true;
+}
+static method main() → dynamic {
+  self::C c = new self::C::•();
+  dynamic x = c.[](0);
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.strong.transformed.expect
new file mode 100644
index 0000000..041d0fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int index) → core::bool
+    return true;
+}
+static method main() → dynamic {
+  self::C c = new self::C::•();
+  core::bool x = c.{self::C::[]}(0);
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.direct.transformed.expect
new file mode 100644
index 0000000..eb9f3f7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int index) → core::bool
+    return true;
+}
+abstract class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method f() → dynamic {
+  self::C c;
+  dynamic x = c.[](0);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.strong.transformed.expect
new file mode 100644
index 0000000..42314d5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_index_op_via_interface.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int index) → core::bool
+    return true;
+}
+abstract class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method f() → dynamic {
+  self::C c;
+  core::bool x = c.{self::I::[]}(0);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.direct.transformed.expect
new file mode 100644
index 0000000..f706c4c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator unary-() → core::bool
+    return true;
+}
+static field self::C c = new self::C::•();
+static field dynamic x = self::c.unary-();
+static method main() → dynamic {
+  self::c;
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.strong.transformed.expect
new file mode 100644
index 0000000..1cb1bde
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator unary-() → core::bool
+    return true;
+}
+static field self::C c = new self::C::•();
+static field core::bool x = self::c.{self::C::unary-}();
+static method main() → dynamic {
+  self::c;
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.direct.transformed.expect
new file mode 100644
index 0000000..d9b94c2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator unary-() → core::bool
+    return true;
+}
+abstract class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C c;
+static field dynamic x = self::c.unary-();
+static method main() → dynamic {
+  self::c;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.strong.transformed.expect
new file mode 100644
index 0000000..c64598e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_custom_unary_op_via_interface.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator unary-() → core::bool
+    return true;
+}
+abstract class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C c;
+static field core::bool x = self::c.{self::I::unary-}();
+static method main() → dynamic {
+  self::c;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.direct.transformed.expect
new file mode 100644
index 0000000..75032d8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method g() → core::bool
+    return true;
+}
+static field dynamic x = self::f().g;
+static method f() → self::C
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..0743802
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method g() → core::bool
+    return true;
+}
+static field () → core::bool x = self::f().{self::C::g};
+static method f() → self::C
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.direct.transformed.expect
new file mode 100644
index 0000000..a3d8939
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method g() → core::bool
+    return true;
+}
+abstract class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic x = self::f().g;
+static method f() → self::C
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.strong.transformed.expect
new file mode 100644
index 0000000..79e16c1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_extract_method_tear_off_via_interface.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method g() → core::bool
+    return true;
+}
+abstract class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field () → core::bool x = self::f().{self::I::g};
+static method f() → self::C
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.direct.transformed.expect
new file mode 100644
index 0000000..89c2a99
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic v = core::print;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..97300eb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_from_top_level_executable_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field (core::Object) → void v = core::print;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.direct.transformed.expect
new file mode 100644
index 0000000..bb3c248
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method g() → core::bool
+    return true;
+}
+static field dynamic x = self::f().g();
+static method f() → self::C
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.strong.transformed.expect
new file mode 100644
index 0000000..5ab65b6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method g() → core::bool
+    return true;
+}
+static field core::bool x = self::f().{self::C::g}();
+static method f() → self::C
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.direct.transformed.expect
new file mode 100644
index 0000000..9a8b19e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method g() → core::bool
+    return true;
+}
+abstract class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic x = self::f().g();
+static method f() → self::C
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.strong.transformed.expect
new file mode 100644
index 0000000..70ba254
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_invoke_method_via_interface.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method g() → core::bool
+    return true;
+}
+abstract class C extends core::Object implements self::I {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::bool x = self::f().{self::I::g}();
+static method f() → self::C
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.direct.transformed.expect
new file mode 100644
index 0000000..4332bc1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::E> values = const <self::E>[self::E::v1];
+  static const field self::E v1 = const self::E::•(0, "E.v1");
+  const constructor •(core::int index, core::String _name) → void
+    : self::E::index = index, self::E::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::E::_name};
+}
+static final field dynamic x = self::E::v1;
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.strong.transformed.expect
new file mode 100644
index 0000000..261820d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::E> values = const <self::E>[self::E::v1];
+  static const field self::E v1 = const self::E::•(0, "E.v1");
+  const constructor •(core::int index, core::String _name) → void
+    : self::E::index = index, self::E::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::E::_name};
+}
+static final field self::E x = self::E::v1;
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.direct.transformed.expect
new file mode 100644
index 0000000..c0ae894
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::E> values = const <self::E>[self::E::v1];
+  static const field self::E v1 = const self::E::•(0, "E.v1");
+  const constructor •(core::int index, core::String _name) → void
+    : self::E::index = index, self::E::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::E::_name};
+}
+static final field dynamic x = self::E::values;
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.strong.transformed.expect
new file mode 100644
index 0000000..9a4f8b8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_enum_values.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class E extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::E> values = const <self::E>[self::E::v1];
+  static const field self::E v1 = const self::E::•(0, "E.v1");
+  const constructor •(core::int index, core::String _name) → void
+    : self::E::index = index, self::E::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::E::_name};
+}
+static final field core::List<self::E> x = self::E::values;
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.direct.transformed.expect
new file mode 100644
index 0000000..b46ce39
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+static final field dynamic x = <core::String, () → void>{};
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.strong.transformed.expect
new file mode 100644
index 0000000..1e61b1d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+static final field core::Map<core::String, () → void> x = <core::String, () → void>{};
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.direct.transformed.expect
new file mode 100644
index 0000000..ab7a925
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = () → T;
+static final field dynamic x = <core::String, () → core::int>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.strong.transformed.expect
new file mode 100644
index 0000000..017095d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_is_typedef_parameterized.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = () → T;
+static final field core::Map<core::String, () → core::int> x = <core::String, () → core::int>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..dd8b091
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic v = <dynamic>[self::f, self::g];
+static method f() → core::int
+  return null;
+static method g() → core::String
+  return null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..55d503c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<() → core::Object> v = <() → core::Object>[self::f, self::g];
+static method f() → core::int
+  return null;
+static method g() → core::String
+  return null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..f4c89c0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic v = <dynamic>[self::f, self::g];
+static method f((core::String) → core::int x) → core::int
+  return null;
+static method g((core::String) → core::int x) → core::String
+  return null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..0472a60
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_function_typed_param.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<((core::String) → core::int) → core::Object> v = <((core::String) → core::int) → core::Object>[self::f, self::g];
+static method f((core::String) → core::int x) → core::int
+  return null;
+static method g((core::String) → core::int x) → core::String
+  return null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..db32f32
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic v = <dynamic>[self::f, self::g];
+static method f({core::int x = null}) → core::int
+  return null;
+static method g({core::int x = null}) → core::String
+  return null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..301d19a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_named_param.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<({x: core::int}) → core::Object> v = <({x: core::int}) → core::Object>[self::f, self::g];
+static method f({core::int x = null}) → core::int
+  return null;
+static method g({core::int x = null}) → core::String
+  return null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..aaa6d2b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic v = <dynamic>[self::f, self::g];
+static method f([core::int x = null]) → core::int
+  return null;
+static method g([core::int x = null]) → core::String
+  return null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..8198998
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_positional_param.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<([core::int]) → core::Object> v = <([core::int]) → core::Object>[self::f, self::g];
+static method f([core::int x = null]) → core::int
+  return null;
+static method g([core::int x = null]) → core::String
+  return null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..336cbf6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic v = <dynamic>[self::f, self::g];
+static method f(core::int x) → core::int
+  return null;
+static method g(core::int x) → core::String
+  return null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..8e9941b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_uses_synthetic_function_type_required_param.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<(core::int) → core::Object> v = <(core::int) → core::Object>[self::f, self::g];
+static method f(core::int x) → core::int
+  return null;
+static method g(core::int x) → core::String
+  return null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.direct.transformed.expect
new file mode 100644
index 0000000..490371e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static final field dynamic f = (core::bool b) → dynamic => (core::int i) → dynamic => <dynamic, dynamic>{i: b};
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.strong.transformed.expect
new file mode 100644
index 0000000..c459ad5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_multiple_levels_of_nesting.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static final field (core::bool) → (core::int) → core::Map<core::int, core::bool> f = (core::bool b) → (core::int) → core::Map<core::int, core::bool> => (core::int i) → core::Map<core::int, core::bool> => <core::int, core::bool>{i: b};
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.direct.transformed.expect
new file mode 100644
index 0000000..aa8b441
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static final field dynamic f = (core::bool b) → dynamic => b;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.strong.transformed.expect
new file mode 100644
index 0000000..ae3f2bd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_depends_on_args.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static final field (core::bool) → core::bool f = (core::bool b) → core::bool => b;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..540dd5f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static final field dynamic f = (core::bool b) → dynamic => 1;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..d46f057
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_field.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static final field (core::bool) → core::int f = (core::bool b) → core::int => 1;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.direct.transformed.expect
new file mode 100644
index 0000000..bac7b39
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static final field dynamic f = (core::bool b) → dynamic => 1;
+static method main() → dynamic {
+  self::f;
+}
diff --git a/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.strong.transformed.expect
new file mode 100644
index 0000000..a28ca70
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inferred_type_via_closure_type_independent_of_args_top_level.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static final field (core::bool) → core::int f = (core::bool b) → core::int => 1;
+static method main() → dynamic {
+  self::f;
+}
diff --git a/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.direct.transformed.expect
new file mode 100644
index 0000000..409a001
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I1 extends core::Object {
+  final field dynamic x = self::y;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class I2 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::num;
+}
+class C extends core::Object implements self::I1, self::I2 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+static field dynamic y = new self::C::•().x;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.strong.transformed.expect
new file mode 100644
index 0000000..cc07a53
--- /dev/null
+++ b/pkg/front_end/testcases/inference/inheritance_does_not_imply_circularity.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class I1 extends core::Object {
+  final field core::int x = self::y;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class I2 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::num;
+}
+class C extends core::Object implements self::I1, self::I2 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+}
+static field core::int y = new self::C::•().{self::C::x};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/instance_creation_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..9a8589f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  constructor •(self::B<core::List<self::A::T>> b) → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic x = new self::A::•<dynamic>(new self::B::•<dynamic>());
+}
diff --git a/pkg/front_end/testcases/inference/instance_creation_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..65851c3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instance_creation_downwards.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  constructor •(self::B<core::List<self::A::T>> b) → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::A<dynamic> x = new self::A::•<dynamic>(new self::B::•<core::List<dynamic>>());
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.direct.transformed.expect
new file mode 100644
index 0000000..7464b33
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>(self::C::f::T x) → self::C::f::T
+    return x;
+  static method g<T extends core::Object>(self::C::g::T x) → self::C::g::T
+    return x;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method test() → void {
+    (core::int) → core::int func;
+    func = super.{self::C::f};
+  }
+}
+static method f<T extends core::Object>(self::f::T x) → self::f::T
+  return x;
+static method test() → void {
+  function h<T extends core::Object>(T x) → T
+    return x;
+  (core::int) → core::int func;
+  func = self::f;
+  func = new self::C::•().f;
+  func = self::C::g;
+  func = h;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.strong.transformed.expect
new file mode 100644
index 0000000..24d056a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>(self::C::f::T x) → self::C::f::T
+    return x;
+  static method g<T extends core::Object>(self::C::g::T x) → self::C::g::T
+    return x;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method test() → void {
+    (core::int) → core::int func;
+    func = super.{self::C::f}<core::int>;
+  }
+}
+static method f<T extends core::Object>(self::f::T x) → self::f::T
+  return x;
+static method test() → void {
+  function h<T extends core::Object>(T x) → T
+    return x;
+  (core::int) → core::int func;
+  func = self::f<core::int>;
+  func = new self::C::•().{self::C::f}<core::int>;
+  func = self::C::g<core::int>;
+  func = h<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.direct.transformed.expect
new file mode 100644
index 0000000..407abc7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends core::Object>(self::C::f::U x) → (self::C::T) → void
+    return (dynamic y) → dynamic {};
+}
+static method test(self::C<core::String> c) → void {
+  (core::int) → (core::String) → void tearoff = c.f;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.transformed.expect
new file mode 100644
index 0000000..d26a271
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_after_contravariance_check.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  generic-contravariant method f<U extends core::Object>(self::C::f::U x) → (self::C::T) → void
+    return (self::C::T y) → core::Null {};
+}
+static method test(self::C<core::String> c) → void {
+  (core::int) → (core::String) → void tearoff = c.{self::C::f} as{TypeError} <U extends core::Object>(U) → (core::String) → void<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.direct.transformed.expect
new file mode 100644
index 0000000..258ba0e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_tearoff_of_call.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test(<T extends core::Object>(T) → T f) → void {
+  (core::int) → core::int func;
+  func = f.call;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.direct.transformed.expect
new file mode 100644
index 0000000..ac05240
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A<T extends core::int> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::B<dynamic> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.strong.transformed.expect
new file mode 100644
index 0000000..1675d51
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_after.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends self::A<core::int>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A<T extends core::int> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::B<self::A<core::int>> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.direct.transformed.expect
new file mode 100644
index 0000000..a8450dd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::int> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::B<dynamic> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.strong.transformed.expect
new file mode 100644
index 0000000..c47d4b1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_has_bound_defined_before.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::int> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends self::A<core::int>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::B<self::A<core::int>> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..d39e0fe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::B<dynamic> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..1b49427
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic2_no_bound.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::B<self::A<dynamic>> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.direct.transformed.expect
new file mode 100644
index 0000000..c31aed4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::int> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A<dynamic> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.strong.transformed.expect
new file mode 100644
index 0000000..250e9df
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_after.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::int> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A<core::int> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.direct.transformed.expect
new file mode 100644
index 0000000..c31aed4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::int> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A<dynamic> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.strong.transformed.expect
new file mode 100644
index 0000000..250e9df
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_generic_has_bound_defined_before.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::int> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A<core::int> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..ab2d9ba
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic v = new self::C::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..8e3e3d3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_no_bound.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::C<dynamic> v = new self::C::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.direct.transformed.expect
new file mode 100644
index 0000000..e062f16
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic x = new self::C::•<core::int>();
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.strong.transformed.expect
new file mode 100644
index 0000000..75d4b70
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_invoke_constructor_type_args_exact.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C<core::int> x = new self::C::•<core::int>();
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.direct.transformed.expect
new file mode 100644
index 0000000..3a30a80
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends self::A> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::B<dynamic> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.strong.transformed.expect
new file mode 100644
index 0000000..7ac3b90d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/instantiate_to_bounds_not_generic.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends self::A> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::B<self::A> v = null;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/int_upwards_local.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/int_upwards_local.dart.direct.transformed.expect
new file mode 100644
index 0000000..da84e28
--- /dev/null
+++ b/pkg/front_end/testcases/inference/int_upwards_local.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library test;
+import self as self;
+
+static method main() → dynamic {
+  dynamic x = 1;
+}
diff --git a/pkg/front_end/testcases/inference/int_upwards_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/int_upwards_local.dart.strong.transformed.expect
new file mode 100644
index 0000000..c1c47e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/int_upwards_local.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int x = 1;
+}
diff --git a/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.direct.transformed.expect
new file mode 100644
index 0000000..6462bb8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method getListOfString() → core::List<core::String>
+  return const <core::String>[];
+static method foo() → void {
+  core::List<dynamic> myList = self::getListOfString();
+  myList.map((dynamic type) → dynamic => 42);
+}
+static method bar() → void {
+  dynamic list;
+  try {
+    list = <core::String>[];
+  }
+  on dynamic catch(final dynamic _) {
+    return;
+  }
+  list.map((dynamic value) → dynamic => "${value}");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.strong.transformed.expect
new file mode 100644
index 0000000..1821742
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_does_not_have_propagated_type_hint.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method getListOfString() → core::List<core::String>
+  return const <core::String>[];
+static method foo() → void {
+  core::List<dynamic> myList = self::getListOfString();
+  myList.{core::Iterable::map}<core::int>((dynamic type) → core::int => 42);
+}
+static method bar() → void {
+  dynamic list;
+  try {
+    list = <core::String>[];
+  }
+  on dynamic catch(final dynamic _) {
+    return;
+  }
+  list.map((dynamic value) → core::String => "${value}");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/lambda_return_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/lambda_return_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..93224a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_return_type.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef FunctionReturningNum = () → core::num;
+static method test() → dynamic {
+  core::int i = 1;
+  core::Object o = 1;
+  () → core::num a = () → dynamic => i;
+  () → core::num b = () → dynamic => o;
+  () → core::num c = () → dynamic {
+    return i;
+  };
+  () → core::num d = () → dynamic {
+    return o;
+  };
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/lambda_return_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/lambda_return_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..ffcd819
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_return_type.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef FunctionReturningNum = () → core::num;
+static method test() → dynamic {
+  core::int i = 1;
+  core::Object o = 1;
+  () → core::num a = () → core::int => i;
+  () → core::num b = () → core::num => o as{TypeError} core::num;
+  () → core::num c = () → core::int {
+    return i;
+  };
+  () → core::num d = () → core::num {
+    return o as{TypeError} core::num;
+  };
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/lambda_void_context.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/lambda_void_context.dart.direct.transformed.expect
new file mode 100644
index 0000000..9848403
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_void_context.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f() → dynamic {
+  core::List<core::int> o;
+  o.forEach((dynamic i) → dynamic => i.+(1));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/lambda_void_context.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/lambda_void_context.dart.strong.transformed.expect
new file mode 100644
index 0000000..f46ab7c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/lambda_void_context.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f() → dynamic {
+  core::List<core::int> o;
+  o.{core::Iterable::forEach}((core::int i) → void => i.{core::num::+}(1));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/list_literal_typed.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/list_literal_typed.dart.direct.transformed.expect
new file mode 100644
index 0000000..9164d78
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literal_typed.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic a = <core::int>[];
+static field dynamic b = <core::double>[1.0, 2.0, 3.0];
+static field dynamic c = <core::List<core::int>>[];
+static field dynamic d = <dynamic>[1, 2.0, false];
+static method main() → dynamic {
+  dynamic a = <core::int>[];
+  dynamic b = <core::double>[1.0, 2.0, 3.0];
+  dynamic c = <core::List<core::int>>[];
+  dynamic d = <dynamic>[1, 2.0, false];
+}
diff --git a/pkg/front_end/testcases/inference/list_literal_typed.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literal_typed.dart.strong.transformed.expect
new file mode 100644
index 0000000..56ceed4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literal_typed.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> a = <core::int>[];
+static field core::List<core::double> b = <core::double>[1.0, 2.0, 3.0];
+static field core::List<core::List<core::int>> c = <core::List<core::int>>[];
+static field core::List<dynamic> d = <dynamic>[1, 2.0, false];
+static method main() → dynamic {
+  core::List<core::int> a = <core::int>[];
+  core::List<core::double> b = <core::double>[1.0, 2.0, 3.0];
+  core::List<core::List<core::int>> c = <core::List<core::int>>[];
+  core::List<dynamic> d = <dynamic>[1, 2.0, false];
+}
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/list_literals.dart.direct.transformed.expect
new file mode 100644
index 0000000..635e4ce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  dynamic x = <dynamic>[1, 2, 3];
+  x.add("hi");
+  x.add(4.0);
+  x.add(4);
+  core::List<core::num> y = x;
+}
+static method test2() → dynamic {
+  dynamic x = <dynamic>[1, 2.0, 3];
+  x.add("hi");
+  x.add(4.0);
+  core::List<core::int> y = x;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
new file mode 100644
index 0000000..661fec7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::List<core::int> x = <core::int>[1, 2, 3];
+  x.{core::List::add}(let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:10:71: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+                                                                      ^");
+  x.{core::List::add}(let final core::double #t2 = 4.0 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:11:71: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+                                                                      ^");
+  x.{core::List::add}(4);
+  core::List<core::num> y = x;
+}
+static method test2() → dynamic {
+  core::List<core::num> x = <core::num>[1, 2.0, 3];
+  x.{core::List::add}(let final core::String #t3 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/list_literals.dart:18:71: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::num'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::num'.
+  x. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+                                                                      ^");
+  x.{core::List::add}(4.0);
+  core::List<core::int> y = x as{TypeError} core::List<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.direct.transformed.expect
new file mode 100644
index 0000000..77948e1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static method test1() → dynamic {
+  dynamic x = <dynamic>[null];
+  x.add(42);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.transformed.expect
new file mode 100644
index 0000000..1c9dd90
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_can_infer_null_bottom.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::List<core::Null> x = <core::Null>[null];
+  x.{core::List::add}(42 as{TypeError} core::Null);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.direct.transformed.expect
new file mode 100644
index 0000000..870df2e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic x1 = <dynamic>[1, 2, 3];
+static field dynamic x2 = <dynamic>[1, 2.0, 3];
+static method test1() → dynamic {
+  self::x1.add("hi");
+  self::x1.add(4.0);
+  self::x1.add(4);
+  core::List<core::num> y = self::x1;
+}
+static method test2() → dynamic {
+  self::x2.add("hi");
+  self::x2.add(4.0);
+  core::List<core::int> y = self::x2;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
new file mode 100644
index 0000000..d9d73c0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/list_literals_top_level.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> x1 = <core::int>[1, 2, 3];
+static field core::List<core::num> x2 = <core::num>[1, 2.0, 3];
+static method test1() → dynamic {
+  self::x1.{core::List::add}(let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:10:72: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+                                                                       ^");
+  self::x1.{core::List::add}(let final core::double #t2 = 4.0 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:11:72: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x1. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0);
+                                                                       ^");
+  self::x1.{core::List::add}(4);
+  core::List<core::num> y = self::x1;
+}
+static method test2() → dynamic {
+  self::x2.{core::List::add}(let final core::String #t3 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/list_literals_top_level.dart:18:72: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::num'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::num'.
+  x2. /*@target=List::add*/ add(/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi');
+                                                                       ^");
+  self::x2.{core::List::add}(4.0);
+  core::List<core::int> y = self::x2 as{TypeError} core::List<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.direct.transformed.expect
new file mode 100644
index 0000000..d80777c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  field self::C::T t;
+  constructor •(self::C::T t) → void
+    : self::C::t = t, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic x = new self::C::•<dynamic>(42);
+  core::num y;
+  self::C<core::int> c_int = new self::C::•<dynamic>(y);
+  self::C<core::num> c_num = new self::C::•<dynamic>(123);
+  dynamic c_dynamic = new self::C::•<dynamic>(42);
+}
diff --git a/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.strong.transformed.expect
new file mode 100644
index 0000000..55e11e2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_constructor_from_arguments.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T t;
+  constructor •(self::C::T t) → void
+    : self::C::t = t, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::C<core::int> x = new self::C::•<core::int>(42);
+  core::num y;
+  self::C<core::int> c_int = new self::C::•<core::int>(y as{TypeError} core::int);
+  self::C<core::num> c_num = new self::C::•<core::num>(123);
+  self::C<dynamic> c_dynamic = new self::C::•<dynamic>(42);
+}
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.direct.transformed.expect
new file mode 100644
index 0000000..5625713
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  asy::Future<core::int> futureInt = null;
+  dynamic x = futureInt;
+}
diff --git a/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.transformed.expect
new file mode 100644
index 0000000..072ead2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_reference_upwards_local.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  asy::Future<core::int> futureInt = null;
+  asy::Future<core::int> x = futureInt;
+}
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.direct.transformed.expect
new file mode 100644
index 0000000..3af0dce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.direct.transformed.expect
@@ -0,0 +1,132 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+typedef IntToInt = (core::int) → core::int;
+static method main() → dynamic {
+  function a() → (core::int) → core::int {
+    return (dynamic x) → dynamic => x;
+  }
+  function b() → asy::Future<(core::int) → core::int> /* originally async */ {
+    final asy::Completer<(core::int) → core::int> :completer = asy::Completer::sync<(core::int) → core::int>();
+    asy::FutureOr<(core::int) → core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = (dynamic x) → dynamic => x;
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+  function c() → core::Iterable<(core::int) → core::int> /* originally sync* */ {
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :sync_op(core::_SyncIterator<(core::int) → core::int> :iterator) → core::bool yielding {
+      {
+        {
+          :iterator.{core::_SyncIterator::_current} = (dynamic x) → dynamic => x;
+          [yield] true;
+        }
+      }
+      return false;
+    }
+    return new core::_SyncIterable::•<(core::int) → core::int>(:sync_op);
+  }
+  function d() → core::Iterable<(core::int) → core::int> /* originally sync* */ {
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :sync_op(core::_SyncIterator<(core::int) → core::int> :iterator) → core::bool yielding {
+      {
+        {
+          :iterator.{core::_SyncIterator::_yieldEachIterable} = <dynamic>[(dynamic x) → dynamic => x];
+          [yield] true;
+        }
+      }
+      return false;
+    }
+    return new core::_SyncIterable::•<(core::int) → core::int>(:sync_op);
+  }
+  function e() → asy::Stream<(core::int) → core::int> /* originally async* */ {
+    asy::_AsyncStarStreamController<(core::int) → core::int> :controller;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try
+        try {
+          #L2:
+          {
+            if(:controller.{asy::_AsyncStarStreamController::add}((dynamic x) → dynamic => x))
+              return null;
+            else
+              [yield] null;
+          }
+          return;
+        }
+        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+          :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+        }
+      finally {
+        :controller.{asy::_AsyncStarStreamController::close}();
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :controller = new asy::_AsyncStarStreamController::•<(core::int) → core::int>(:async_op);
+    return :controller.{asy::_AsyncStarStreamController::stream};
+  }
+  function f() → asy::Stream<(core::int) → core::int> /* originally async* */ {
+    asy::_AsyncStarStreamController<(core::int) → core::int> :controller;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try
+        try {
+          #L3:
+          {
+            if(:controller.{asy::_AsyncStarStreamController::addStream}(asy::Stream::fromIterable<dynamic>(<dynamic>[(dynamic x) → dynamic => x])))
+              return null;
+            else
+              [yield] null;
+          }
+          return;
+        }
+        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+          :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+        }
+      finally {
+        :controller.{asy::_AsyncStarStreamController::close}();
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :controller = new asy::_AsyncStarStreamController::•<(core::int) → core::int>(:async_op);
+    return :controller.{asy::_AsyncStarStreamController::stream};
+  }
+}
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
new file mode 100644
index 0000000..001a311
--- /dev/null
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
@@ -0,0 +1,135 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+typedef IntToInt = (core::int) → core::int;
+static method main() → dynamic {
+  function a() → (core::int) → core::int {
+    return (core::int x) → core::int => x;
+  }
+  function b() → asy::Future<(core::int) → core::int> /* originally async */ {
+    final asy::Completer<(core::int) → core::int> :completer = asy::Completer::sync<(core::int) → core::int>();
+    asy::FutureOr<(core::int) → core::int> :return_value;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = let final (dynamic) → dynamic #t1 = (dynamic x) → dynamic => x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:36: Error: A value of type '(dynamic) \u8594 dynamic' can't be assigned to a variable of type 'dart.async::FutureOr<(dart.core::int) \u8594 dart.core::int>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.async::FutureOr<(dart.core::int) \u8594 dart.core::int>'.
+    return /*@returnType=dynamic*/ (/*@type=dynamic*/ x) => x;
+                                   ^";
+          break #L1;
+        }
+        :completer.{asy::Completer::complete}(:return_value);
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    asy::Future::microtask<dynamic>(:async_op);
+    return :completer.{asy::Completer::future};
+  }
+  function c() → core::Iterable<(core::int) → core::int> /* originally sync* */ {
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :sync_op(core::_SyncIterator<(core::int) → core::int> :iterator) → core::bool yielding {
+      {
+        {
+          :iterator.{core::_SyncIterator::_current} = (core::int x) → core::int => x;
+          [yield] true;
+        }
+      }
+      return false;
+    }
+    return new core::_SyncIterable::•<(core::int) → core::int>(:sync_op);
+  }
+  function d() → core::Iterable<(core::int) → core::int> /* originally sync* */ {
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :sync_op(core::_SyncIterator<(core::int) → core::int> :iterator) → core::bool yielding {
+      {
+        {
+          :iterator.{core::_SyncIterator::_yieldEachIterable} = <(core::int) → core::int>[(core::int x) → core::int => x];
+          [yield] true;
+        }
+      }
+      return false;
+    }
+    return new core::_SyncIterable::•<(core::int) → core::int>(:sync_op);
+  }
+  function e() → asy::Stream<(core::int) → core::int> /* originally async* */ {
+    asy::_AsyncStarStreamController<(core::int) → core::int> :controller;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try
+        try {
+          #L2:
+          {
+            if(:controller.{asy::_AsyncStarStreamController::add}((core::int x) → core::int => x))
+              return null;
+            else
+              [yield] null;
+          }
+          return;
+        }
+        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+          :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+        }
+      finally {
+        :controller.{asy::_AsyncStarStreamController::close}();
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :controller = new asy::_AsyncStarStreamController::•<(core::int) → core::int>(:async_op);
+    return :controller.{asy::_AsyncStarStreamController::stream};
+  }
+  function f() → asy::Stream<(core::int) → core::int> /* originally async* */ {
+    asy::_AsyncStarStreamController<(core::int) → core::int> :controller;
+    dynamic :async_stack_trace;
+    dynamic :async_op_then;
+    dynamic :async_op_error;
+    dynamic :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    dynamic :saved_try_context_var0;
+    dynamic :saved_try_context_var1;
+    function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+      try
+        try {
+          #L3:
+          {
+            if(:controller.{asy::_AsyncStarStreamController::addStream}(asy::Stream::fromIterable<(core::int) → core::int>(<(core::int) → core::int>[(core::int x) → core::int => x])))
+              return null;
+            else
+              [yield] null;
+          }
+          return;
+        }
+        on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+          :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+        }
+      finally {
+        :controller.{asy::_AsyncStarStreamController::close}();
+      }
+    :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :controller = new asy::_AsyncStarStreamController::•<(core::int) → core::int>(:async_op);
+    return :controller.{asy::_AsyncStarStreamController::stream};
+  }
+}
diff --git a/pkg/front_end/testcases/inference/logical_or_promotion.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/logical_or_promotion.dart.direct.transformed.expect
new file mode 100644
index 0000000..0216b64
--- /dev/null
+++ b/pkg/front_end/testcases/inference/logical_or_promotion.dart.direct.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field self::A a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::Object o) → void {
+    if(o is self::A || o is self::B) {
+      if(o is self::A) {
+        this.{self::C::a} = o{self::A};
+      }
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/logical_or_promotion.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/logical_or_promotion.dart.strong.transformed.expect
new file mode 100644
index 0000000..0216b64
--- /dev/null
+++ b/pkg/front_end/testcases/inference/logical_or_promotion.dart.strong.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field self::A a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::Object o) → void {
+    if(o is self::A || o is self::B) {
+      if(o is self::A) {
+        this.{self::C::a} = o{self::A};
+      }
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/map_literals.dart.direct.transformed.expect
new file mode 100644
index 0000000..d8d0587
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  dynamic x = <dynamic, dynamic>{1: "x", 2: "y"};
+  x.[]=(3, "z");
+  x.[]=("hi", "w");
+  x.[]=(4.0, "u");
+  x.[]=(3, 42);
+  core::Map<core::num, core::String> y = x;
+}
+static method test2() → dynamic {
+  dynamic x = <dynamic, dynamic>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
+  x.[]=(3, "z");
+  x.[]=("hi", "w");
+  x.[]=(4.0, "u");
+  x.[]=(3, 42);
+  core::Pattern p = null;
+  x.[]=(2, p);
+  core::Map<core::int, core::String> y = x;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
new file mode 100644
index 0000000..cd5924f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::Map<core::int, core::String> x = <core::int, core::String>{1: "x", 2: "y"};
+  x.{core::Map::[]=}(3, "z");
+  x.{core::Map::[]=}(let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:12:46: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+                                             ^", "w");
+  x.{core::Map::[]=}(let final core::double #t2 = 4.0 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:14:46: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+      /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
+                                             ^", "u");
+  x.{core::Map::[]=}(3, let final core::int #t3 = 42 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:15:61: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+                                                            ^");
+  core::Map<core::num, core::String> y = x;
+}
+static method test2() → dynamic {
+  core::Map<core::num, core::Pattern> x = <core::num, core::Pattern>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
+  x.{core::Map::[]=}(3, "z");
+  x.{core::Map::[]=}(let final core::String #t4 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:27:46: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::num'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::num'.
+      /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+                                             ^", "w");
+  x.{core::Map::[]=}(4.0, "u");
+  x.{core::Map::[]=}(3, let final core::int #t5 = 42 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/map_literals.dart:29:61: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::Pattern'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::Pattern'.
+  x /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+                                                            ^");
+  core::Pattern p = null;
+  x.{core::Map::[]=}(2, p);
+  core::Map<core::int, core::String> y = x as{TypeError} core::Map<core::int, core::String>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.direct.transformed.expect
new file mode 100644
index 0000000..ba57d25
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static method test1() → dynamic {
+  dynamic x = <dynamic, dynamic>{null: null};
+  x.[]=(3, "z");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.transformed.expect
new file mode 100644
index 0000000..c7c099c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_can_infer_null.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::Map<core::Null, core::Null> x = <core::Null, core::Null>{null: null};
+  x.{core::Map::[]=}(3 as{TypeError} core::Null, "z" as{TypeError} core::Null);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.direct.transformed.expect
new file mode 100644
index 0000000..f17ed4f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic x1 = <dynamic, dynamic>{1: "x", 2: "y"};
+static field dynamic x2 = <dynamic, dynamic>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
+static method test1() → dynamic {
+  self::x1.[]=(3, "z");
+  self::x1.[]=("hi", "w");
+  self::x1.[]=(4.0, "u");
+  self::x1.[]=(3, 42);
+  core::Map<core::num, core::String> y = self::x1;
+}
+static method test2() → dynamic {
+  self::x2.[]=(3, "z");
+  self::x2.[]=("hi", "w");
+  self::x2.[]=(4.0, "u");
+  self::x2.[]=(3, 42);
+  core::Pattern p = null;
+  self::x2.[]=(2, p);
+  core::Map<core::int, core::String> y = self::x2;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
new file mode 100644
index 0000000..bf1d957
--- /dev/null
+++ b/pkg/front_end/testcases/inference/map_literals_top_level.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::Map<core::int, core::String> x1 = <core::int, core::String>{1: "x", 2: "y"};
+static field core::Map<core::num, core::Pattern> x2 = <core::num, core::Pattern>{1: "x", 2: "y", 3.0: core::RegExp::•(".")};
+static method test1() → dynamic {
+  self::x1.{core::Map::[]=}(3, "z");
+  self::x1.{core::Map::[]=}(let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:14:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+                                                                  ^", "w");
+  self::x1.{core::Map::[]=}(let final core::double #t2 = 4.0 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:15:67: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  x1 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 4.0] = 'u';
+                                                                  ^", "u");
+  self::x1.{core::Map::[]=}(3, let final core::int #t3 = 42 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:16:62: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  x1 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+                                                             ^");
+  core::Map<core::num, core::String> y = self::x1;
+}
+static method test2() → dynamic {
+  self::x2.{core::Map::[]=}(3, "z");
+  self::x2.{core::Map::[]=}(let final core::String #t4 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:27:67: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::num'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::num'.
+  x2 /*@target=Map::[]=*/ [/*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/ 'hi'] = 'w';
+                                                                  ^", "w");
+  self::x2.{core::Map::[]=}(4.0, "u");
+  self::x2.{core::Map::[]=}(3, let final core::int #t5 = 42 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/map_literals_top_level.dart:29:62: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'dart.core::Pattern'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::Pattern'.
+  x2 /*@target=Map::[]=*/ [3] = /*error:INVALID_ASSIGNMENT*/ 42;
+                                                             ^");
+  core::Pattern p = null;
+  self::x2.{core::Map::[]=}(2, p);
+  core::Map<core::int, core::String> y = self::x2 as{TypeError} core::Map<core::int, core::String>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.direct.transformed.expect
new file mode 100644
index 0000000..0d4c4d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>() → self::D<self::C::f::T>
+    return null;
+}
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic f = new self::C::•().f<core::int>();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.strong.transformed.expect
new file mode 100644
index 0000000..28b0bd9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>() → self::D<self::C::f::T>
+    return null;
+}
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::D<core::int> f = new self::C::•().{self::C::f}<core::int>();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.direct.transformed.expect
new file mode 100644
index 0000000..2409e0e2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>() → self::D<self::C::f::T>
+    return null;
+}
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C c;
+static field dynamic f = self::c.f<core::int>();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.strong.transformed.expect
new file mode 100644
index 0000000..e7701fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_instance_method_identifier_sequence.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>() → self::D<self::C::f::T>
+    return null;
+}
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C c;
+static field self::D<core::int> f = self::c.{self::C::f}<core::int>();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.direct.transformed.expect
new file mode 100644
index 0000000..f986cdf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method f<T extends core::Object>() → self::D<self::C::f::T>
+    return null;
+}
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic f = self::C::f<core::int>();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.strong.transformed.expect
new file mode 100644
index 0000000..5a6e1b5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_static_method.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method f<T extends core::Object>() → self::D<self::C::f::T>
+    return null;
+}
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::D<core::int> f = self::C::f<core::int>();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.direct.transformed.expect
new file mode 100644
index 0000000..9b0f603
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic g = self::f<core::int>();
+static method f<T extends core::Object>() → self::D<self::f::T>
+  return null;
+static method main() → dynamic {
+  self::g;
+}
diff --git a/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.strong.transformed.expect
new file mode 100644
index 0000000..711c11f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/method_call_with_type_arguments_top_level_function.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::D<core::int> g = self::f<core::int>();
+static method f<T extends core::Object>() → self::D<self::f::T>
+  return null;
+static method main() → dynamic {
+  self::g;
+}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.direct.transformed.expect
new file mode 100644
index 0000000..babd076
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.direct.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<X extends core::Object, Y extends core::String> extends self::I<self::M0::X> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1 extends core::Object implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&M1&M0 extends self::M1 implements self::M0<dynamic, dynamic> {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+class A extends self::_A&M1&M0 {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.strong.transformed.expect
new file mode 100644
index 0000000..3dfcef8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_1.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<X extends core::Object, Y extends core::String> extends self::I<self::M0::X> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1 extends core::Object implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&M1&M0 extends self::M1 implements self::M0<core::int, core::String> {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+class A extends self::_A&M1&M0 {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..88b88c5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.direct.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<X extends core::Object, Y extends self::M0::X> extends self::I<self::M0::X> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1 extends core::Object implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&M1&M0 extends self::M1 implements self::M0<dynamic, dynamic> {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+class A extends self::_A&M1&M0 {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..db58674
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_2.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<X extends core::Object, Y extends self::M0::X> extends self::I<self::M0::X> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1 extends core::Object implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&M1&M0 extends self::M1 implements self::M0<core::int, core::int> {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+class A extends self::_A&M1&M0 {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.direct.transformed.expect
new file mode 100644
index 0000000..af781d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.direct.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<X extends core::Object, Y extends core::Comparable<self::M0::Y>> extends self::I<self::M0::X> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1 extends core::Object implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&M1&M0 extends self::M1 implements self::M0<dynamic, dynamic> {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+class A extends self::_A&M1&M0 {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.transformed.expect
new file mode 100644
index 0000000..c7f6535
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_instantiate_to_bounds_3.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<X extends core::Object, Y extends core::Comparable<self::M0::Y>> extends self::I<self::M0::X> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1 extends core::Object implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&M1&M0 extends self::M1 implements self::M0<core::int, core::Comparable<dynamic>> {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+class A extends self::_A&M1&M0 {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.direct.transformed.expect
new file mode 100644
index 0000000..6bd4312
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.direct.transformed.expect
@@ -0,0 +1,45 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class J<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _M0&I&J<X extends core::Object, Y extends core::Object> extends self::I<self::_M0&I&J::X> implements self::J<self::_M0&I&J::Y> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M0<X extends core::Object, Y extends core::Object> extends self::_M0&I&J<self::M0::X, self::M0::Y> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1 extends core::Object implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M2 extends self::M1 implements self::J<core::double> {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+abstract class _A&M2&M0 extends self::M2 implements self::M0<dynamic, dynamic> {
+  synthetic constructor •() → void
+    : super self::M2::•()
+    ;
+}
+class A extends self::_A&M2&M0 {
+  synthetic constructor •() → void
+    : super self::M2::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.strong.transformed.expect
new file mode 100644
index 0000000..b0a644f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_multiple_constraints.dart.strong.transformed.expect
@@ -0,0 +1,45 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class J<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _M0&I&J<X extends core::Object, Y extends core::Object> extends self::I<self::_M0&I&J::X> implements self::J<self::_M0&I&J::Y> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M0<X extends core::Object, Y extends core::Object> extends self::_M0&I&J<self::M0::X, self::M0::Y> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1 extends core::Object implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M2 extends self::M1 implements self::J<core::double> {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+abstract class _A&M2&M0 extends self::M2 implements self::M0<core::int, core::double> {
+  synthetic constructor •() → void
+    : super self::M2::•()
+    ;
+}
+class A extends self::_A&M2&M0 {
+  synthetic constructor •() → void
+    : super self::M2::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.direct.transformed.expect
new file mode 100644
index 0000000..47d99df
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.direct.transformed.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<T extends core::Object> extends self::I<core::List<self::M0::T>> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1<T extends core::Object> extends self::I<core::List<self::M1::T>> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M2<T extends core::Object> extends self::M1<core::Map<self::M2::T, self::M2::T>> {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+abstract class _A&M2&M0 extends self::M2<core::int> implements self::M0<dynamic> {
+  synthetic constructor •() → void
+    : super self::M2::•()
+    ;
+}
+class A extends self::_A&M2&M0 {
+  synthetic constructor •() → void
+    : super self::M2::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.strong.transformed.expect
new file mode 100644
index 0000000..bab9455
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_non_trivial_constraints.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<T extends core::Object> extends self::I<core::List<self::M0::T>> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1<T extends core::Object> extends self::I<core::List<self::M1::T>> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M2<T extends core::Object> extends self::M1<core::Map<self::M2::T, self::M2::T>> {
+  synthetic constructor •() → void
+    : super self::M1::•()
+    ;
+}
+abstract class _A&M2&M0 extends self::M2<core::int> implements self::M0<core::Map<core::int, core::int>> {
+  synthetic constructor •() → void
+    : super self::M2::•()
+    ;
+}
+class A extends self::_A&M2&M0 {
+  synthetic constructor •() → void
+    : super self::M2::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.direct.transformed.expect
new file mode 100644
index 0000000..94e9c02
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.direct.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<T extends core::Object> extends self::I<self::M0::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1<T extends core::Object> extends self::I<self::M1::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+abstract class _A&M0&M1 extends self::M0<core::int> implements self::M1<dynamic> {
+  synthetic constructor •() → void
+    : super self::M0::•()
+    ;
+}
+class A extends self::_A&M0&M1 {
+  synthetic constructor •() → void
+    : super self::M0::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.strong.transformed.expect
new file mode 100644
index 0000000..f1c52e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_1.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<T extends core::Object> extends self::I<self::M0::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1<T extends core::Object> extends self::I<self::M1::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+abstract class _A&M0&M1 extends self::M0<core::int> implements self::M1<core::int> {
+  synthetic constructor •() → void
+    : super self::M0::•()
+    ;
+}
+class A extends self::_A&M0&M1 {
+  synthetic constructor •() → void
+    : super self::M0::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..3988528
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.direct.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<T extends core::Object> extends self::I<self::M0::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1<T extends core::Object> extends self::I<self::M1::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M2<T extends core::Object> extends self::I<self::M2::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+abstract class _A&M0&M1 extends self::M0<core::int> implements self::M1<dynamic> {
+  synthetic constructor •() → void
+    : super self::M0::•()
+    ;
+}
+abstract class _A&M0&M1&M2 extends self::_A&M0&M1 implements self::M2<dynamic> {
+  synthetic constructor •() → void
+    : super self::_A&M0&M1::•()
+    ;
+}
+class A extends self::_A&M0&M1&M2 {
+  synthetic constructor •() → void
+    : super self::M0::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..42ec419
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_2.dart.strong.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<T extends core::Object> extends self::I<self::M0::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M1<T extends core::Object> extends self::I<self::M1::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+class M2<T extends core::Object> extends self::I<self::M2::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+abstract class _A&M0&M1 extends self::M0<core::int> implements self::M1<core::int> {
+  synthetic constructor •() → void
+    : super self::M0::•()
+    ;
+}
+abstract class _A&M0&M1&M2 extends self::_A&M0&M1 implements self::M2<core::int> {
+  synthetic constructor •() → void
+    : super self::_A&M0&M1::•()
+    ;
+}
+class A extends self::_A&M0&M1&M2 {
+  synthetic constructor •() → void
+    : super self::M0::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.direct.transformed.expect
new file mode 100644
index 0000000..e737000
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart.direct.transformed.expect
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<T extends core::Object> extends core::Object implements self::I<self::M0::T> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M1<T extends core::Object> extends self::I<self::M1::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+abstract class _A&Object&M0 extends core::Object implements self::M0<dynamic> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&Object&M0&M1 extends self::_A&Object&M0 implements self::M1<core::int> {
+  synthetic constructor •() → void
+    : super self::_A&Object&M0::•()
+    ;
+}
+class A extends self::_A&Object&M0&M1 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/mixin_inference_outwards_3.dart:15:38: Error: 'A' can't implement both '#lib1::I<dynamic>' and '#lib1::I<dart.core::int>'
+class /*@error=AmbiguousSupertypes*/ A extends Object with M0, M1<int> {}
+                                     ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.direct.transformed.expect
new file mode 100644
index 0000000..2b4d638
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart.direct.transformed.expect
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<T extends core::Object> extends core::Object implements self::I<self::M0::T> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M1<T extends core::Object> extends self::I<self::M1::T> {
+  synthetic constructor •() → void
+    : super self::I::•()
+    ;
+}
+abstract class _A&Object&M0 extends core::Object implements self::M0<dynamic> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&Object&M0&M1 extends self::_A&Object&M0 implements self::M1<dynamic> {
+  synthetic constructor •() → void
+    : super self::_A&Object&M0::•()
+    ;
+}
+class A extends self::_A&Object&M0&M1 implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/mixin_inference_outwards_4.dart:16:38: Error: 'A' can't implement both '#lib1::I<dynamic>' and '#lib1::I<dart.core::int>'
+class /*@error=AmbiguousSupertypes*/ A extends Object
+                                     ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.direct.transformed.expect
new file mode 100644
index 0000000..1f32528
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_1.dart.direct.transformed.expect
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<T extends core::Object> extends core::Object implements self::I<self::M0::T, core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M1<T extends core::Object> extends core::Object implements self::I<core::String, self::M1::T> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&Object&M0 extends core::Object implements self::M0<dynamic> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&Object&M0&M1 extends self::_A&Object&M0 implements self::M1<dynamic> {
+  synthetic constructor •() → void
+    : super self::_A&Object&M0::•()
+    ;
+}
+class A extends self::_A&Object&M0&M1 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/mixin_inference_unification_1.dart:15:38: Error: 'A' can't implement both '#lib1::I<dynamic, dart.core::int>' and '#lib1::I<dart.core::String, dynamic>'
+class /*@error=AmbiguousSupertypes*/ A extends Object with M0, M1 {}
+                                     ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..3819847
--- /dev/null
+++ b/pkg/front_end/testcases/inference/mixin_inference_unification_2.dart.direct.transformed.expect
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class I<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M0<T extends core::Object> extends core::Object implements self::I<self::M0::T, core::List<self::M0::T>> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M1<T extends core::Object> extends core::Object implements self::I<core::List<self::M1::T>, self::M1::T> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&Object&M0 extends core::Object implements self::M0<dynamic> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&Object&M0&M1 extends self::_A&Object&M0 implements self::M1<dynamic> {
+  synthetic constructor •() → void
+    : super self::_A&Object&M0::•()
+    ;
+}
+class A extends self::_A&Object&M0&M1 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference/mixin_inference_unification_2.dart:19:38: Error: 'A' can't implement both '#lib1::I<dynamic, dart.core::List<dynamic>>' and '#lib1::I<dart.core::List<dynamic>, dynamic>'
+class /*@error=AmbiguousSupertypes*/ A extends Object with M0, M1 {}
+                                     ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.direct.transformed.expect
new file mode 100644
index 0000000..f130963
--- /dev/null
+++ b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::num x = 3;
+  x = null;
+}
+static method main() → dynamic {
+  self::test1();
+}
diff --git a/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.strong.transformed.expect
new file mode 100644
index 0000000..f130963
--- /dev/null
+++ b/pkg/front_end/testcases/inference/no_error_when_declared_type_is_num_and_assigned_null.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test1() → dynamic {
+  core::num x = 3;
+  x = null;
+}
+static method main() → dynamic {
+  self::test1();
+}
diff --git a/pkg/front_end/testcases/inference/non_const_invocation.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/non_const_invocation.dart.direct.transformed.expect
new file mode 100644
index 0000000..a535f30
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_const_invocation.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<U extends core::Object, V extends core::Object> = (U) → V;
+class Foo<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get v1() → self::Bar<self::Foo::T>
+    return new self::Bar::•<dynamic>();
+  get v2() → self::Bar<core::List<self::Foo::T>>
+    return new self::Bar::•<dynamic>();
+  get v3() → self::Bar<(self::Foo::T) → self::Foo::T>
+    return new self::Bar::•<dynamic>();
+  get v4() → self::Bar<((self::Foo::T) → self::Foo::T) → self::Foo::T>
+    return new self::Bar::•<dynamic>();
+  get v5() → core::List<self::Foo::T>
+    return <dynamic>[];
+  get v6() → core::List<(self::Foo::T) → self::Foo::T>
+    return <dynamic>[];
+  get v7() → core::Map<self::Foo::T, self::Foo::T>
+    return <dynamic, dynamic>{};
+  get v8() → core::Map<(self::Foo::T) → self::Foo::T, self::Foo::T>
+    return <dynamic, dynamic>{};
+  get v9() → core::Map<self::Foo::T, (self::Foo::T) → self::Foo::T>
+    return <dynamic, dynamic>{};
+}
+class Bar<T extends core::Object> extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.transformed.expect
new file mode 100644
index 0000000..e409ade
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_const_invocation.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<U extends core::Object, V extends core::Object> = (U) → V;
+class Foo<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get v1() → self::Bar<self::Foo::T>
+    return new self::Bar::•<self::Foo::T>();
+  get v2() → self::Bar<core::List<self::Foo::T>>
+    return new self::Bar::•<core::List<self::Foo::T>>();
+  generic-contravariant get v3() → self::Bar<(self::Foo::T) → self::Foo::T>
+    return new self::Bar::•<(self::Foo::T) → self::Foo::T>();
+  generic-contravariant get v4() → self::Bar<((self::Foo::T) → self::Foo::T) → self::Foo::T>
+    return new self::Bar::•<((self::Foo::T) → self::Foo::T) → self::Foo::T>();
+  get v5() → core::List<self::Foo::T>
+    return <self::Foo::T>[];
+  generic-contravariant get v6() → core::List<(self::Foo::T) → self::Foo::T>
+    return <(self::Foo::T) → self::Foo::T>[];
+  get v7() → core::Map<self::Foo::T, self::Foo::T>
+    return <self::Foo::T, self::Foo::T>{};
+  generic-contravariant get v8() → core::Map<(self::Foo::T) → self::Foo::T, self::Foo::T>
+    return <(self::Foo::T) → self::Foo::T, self::Foo::T>{};
+  generic-contravariant get v9() → core::Map<self::Foo::T, (self::Foo::T) → self::Foo::T>
+    return <self::Foo::T, (self::Foo::T) → self::Foo::T>{};
+}
+class Bar<T extends core::Object> extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..dab4a13
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → dynamic
+    return null;
+  set x(dynamic value) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..dab4a13
--- /dev/null
+++ b/pkg/front_end/testcases/inference/non_inferrable_getter_setter.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → dynamic
+    return null;
+  set x(dynamic value) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.direct.transformed.expect
new file mode 100644
index 0000000..68554e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → core::int
+    return null;
+}
+static method g(self::C c) → dynamic {
+  dynamic x = let final dynamic #t1 = c in #t1.==(null) ? null : #t1.f();
+  let final dynamic #t2 = c in #t2.==(null) ? null : #t2.f();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.transformed.expect
new file mode 100644
index 0000000..1fc9581
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_method_invocation.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → core::int
+    return null;
+}
+static method g(self::C c) → dynamic {
+  core::int x = let final self::C #t1 = c in #t1.==(null) ?{core::int} null : #t1.{self::C::f}();
+  let final self::C #t2 = c in #t2.==(null) ?{core::int} null : #t2.{self::C::f}();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/null_aware_property_get.dart.direct.transformed.expect
new file mode 100644
index 0000000..4b22e8a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method f(self::C c) → void {
+  dynamic x = let final dynamic #t1 = c in #t1.==(null) ? null : #t1.x;
+  let final dynamic #t2 = c in #t2.==(null) ? null : #t2.x;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.transformed.expect
new file mode 100644
index 0000000..d8a523e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_aware_property_get.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method f(self::C c) → void {
+  core::int x = let final self::C #t1 = c in #t1.==(null) ?{core::int} null : #t1.{self::C::x};
+  let final self::C #t2 = c in #t2.==(null) ?{core::int} null : #t2.{self::C::x};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.direct.transformed.expect
new file mode 100644
index 0000000..a976d56
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::List<core::int> x;
+  dynamic y = let final dynamic #t1 = x in #t1.==(null) ? <dynamic>[] : #t1;
+  core::List<core::int> z = y;
+}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.transformed.expect
new file mode 100644
index 0000000..a6ef2bf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::List<core::int> x;
+  core::List<core::int> y = let final core::List<core::int> #t1 = x in #t1.==(null) ?{core::List<core::int>} <core::int>[] : #t1;
+  core::List<core::int> z = y;
+}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..5e3c00d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::List<core::int> x;
+  core::List<core::num> y = let final dynamic #t1 = x in #t1.==(null) ? <dynamic>[] : #t1;
+}
diff --git a/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..033616f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_coalescing_operator_2.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::List<core::int> x;
+  core::List<core::num> y = let final core::List<core::int> #t1 = x in #t1.==(null) ?{core::List<core::num>} <core::num>[] : #t1;
+}
diff --git a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.direct.transformed.expect
new file mode 100644
index 0000000..f592726
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic h = null;
+static method foo((core::Object) → core::int f) → void {}
+static method test() → dynamic {
+  dynamic f = (core::Object x) → dynamic => null;
+  core::String y = f.call(42);
+  f = (dynamic x) → dynamic => "hello";
+  dynamic g = null;
+  g = "hello";
+  g.foo();
+  self::h = "hello";
+  self::h.foo();
+  self::foo((dynamic x) → dynamic => null);
+  self::foo((dynamic x) → dynamic => throw "not implemented");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.transformed.expect
new file mode 100644
index 0000000..00a18ed
--- /dev/null
+++ b/pkg/front_end/testcases/inference/null_literal_should_not_infer_as_bottom.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic h = null;
+static method foo((core::Object) → core::int f) → void {}
+static method test() → dynamic {
+  (core::Object) → core::Null f = (core::Object x) → core::Null => null;
+  core::String y = f.call(42);
+  f = (core::Object x) → core::Null => "hello" as{TypeError} core::Null;
+  dynamic g = null;
+  g = "hello";
+  g.foo();
+  self::h = "hello";
+  self::h.foo();
+  self::foo((core::Object x) → core::Null => null);
+  self::foo((core::Object x) → <BottomType>=> throw "not implemented");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/overloaded_int_operators.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.direct.transformed.expect
new file mode 100644
index 0000000..b45cd7e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.direct.transformed.expect
@@ -0,0 +1,45 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::num n = 1;
+  core::int i = 1;
+  core::double d = 1.0;
+  dynamic ddPlus = d.+(d);
+  dynamic ddMinus = d.-(d);
+  dynamic ddTimes = d.*(d);
+  dynamic ddMod = d.%(d);
+  dynamic diPlus = d.+(i);
+  dynamic diMinus = d.-(i);
+  dynamic diTimes = d.*(i);
+  dynamic diMod = d.%(i);
+  dynamic dnPlus = d.+(n);
+  dynamic dnMinus = d.-(n);
+  dynamic dnTimes = d.*(n);
+  dynamic dnMod = d.%(n);
+  dynamic idPlus = i.+(d);
+  dynamic idMinus = i.-(d);
+  dynamic idTimes = i.*(d);
+  dynamic idMod = i.%(d);
+  dynamic iiPlus = i.+(i);
+  dynamic iiMinus = i.-(i);
+  dynamic iiTimes = i.*(i);
+  dynamic iiMod = i.%(i);
+  dynamic inPlus = i.+(n);
+  dynamic inMinus = i.-(n);
+  dynamic inTimes = i.*(n);
+  dynamic inMod = i.%(n);
+  dynamic ndPlus = n.+(d);
+  dynamic ndMinus = n.-(d);
+  dynamic ndTimes = n.*(d);
+  dynamic ndMod = n.%(d);
+  dynamic niPlus = n.+(i);
+  dynamic niMinus = n.-(i);
+  dynamic niTimes = n.*(i);
+  dynamic niMod = n.%(i);
+  dynamic nnPlus = n.+(n);
+  dynamic nnMinus = n.-(n);
+  dynamic nnTimes = n.*(n);
+  dynamic nnMod = n.%(n);
+}
diff --git a/pkg/front_end/testcases/inference/overloaded_int_operators.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.strong.transformed.expect
new file mode 100644
index 0000000..8eaa200
--- /dev/null
+++ b/pkg/front_end/testcases/inference/overloaded_int_operators.dart.strong.transformed.expect
@@ -0,0 +1,45 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::num n = 1;
+  core::int i = 1;
+  core::double d = 1.0;
+  core::double ddPlus = d.{core::double::+}(d);
+  core::double ddMinus = d.{core::double::-}(d);
+  core::double ddTimes = d.{core::double::*}(d);
+  core::double ddMod = d.{core::double::%}(d);
+  core::double diPlus = d.{core::double::+}(i);
+  core::double diMinus = d.{core::double::-}(i);
+  core::double diTimes = d.{core::double::*}(i);
+  core::double diMod = d.{core::double::%}(i);
+  core::double dnPlus = d.{core::double::+}(n);
+  core::double dnMinus = d.{core::double::-}(n);
+  core::double dnTimes = d.{core::double::*}(n);
+  core::double dnMod = d.{core::double::%}(n);
+  core::double idPlus = i.{core::num::+}(d);
+  core::double idMinus = i.{core::num::-}(d);
+  core::double idTimes = i.{core::num::*}(d);
+  core::double idMod = i.{core::num::%}(d);
+  core::int iiPlus = i.{core::num::+}(i);
+  core::int iiMinus = i.{core::num::-}(i);
+  core::int iiTimes = i.{core::num::*}(i);
+  core::int iiMod = i.{core::num::%}(i);
+  core::num inPlus = i.{core::num::+}(n);
+  core::num inMinus = i.{core::num::-}(n);
+  core::num inTimes = i.{core::num::*}(n);
+  core::num inMod = i.{core::num::%}(n);
+  core::num ndPlus = n.{core::num::+}(d);
+  core::num ndMinus = n.{core::num::-}(d);
+  core::num ndTimes = n.{core::num::*}(d);
+  core::num ndMod = n.{core::num::%}(d);
+  core::num niPlus = n.{core::num::+}(i);
+  core::num niMinus = n.{core::num::-}(i);
+  core::num niTimes = n.{core::num::*}(i);
+  core::num niMod = n.{core::num::%}(i);
+  core::num nnPlus = n.{core::num::+}(n);
+  core::num nnMinus = n.{core::num::-}(n);
+  core::num nnTimes = n.{core::num::*}(n);
+  core::num nnMod = n.{core::num::%}(n);
+}
diff --git a/pkg/front_end/testcases/inference/override_equals.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/override_equals.dart.direct.transformed.expect
new file mode 100644
index 0000000..6ffe3a7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_equals.dart.direct.transformed.expect
@@ -0,0 +1,36 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class NullEquality extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  @core::override
+  operator ==(core::Object other) → core::Null
+    return null;
+}
+class SubNullEquality extends self::NullEquality {
+  synthetic constructor •() → void
+    : super self::NullEquality::•()
+    ;
+  method test() → void {
+    dynamic super_equals_self = super.{self::NullEquality::==}(this);
+    dynamic super_equals_null = super.{self::NullEquality::==}(null);
+    dynamic super_not_equals_self = !super.{self::NullEquality::==}(this);
+    dynamic super_not_equals_null = !super.{self::NullEquality::==}(null);
+  }
+}
+static method test() → dynamic {
+  self::NullEquality n = new self::NullEquality::•();
+  dynamic equals_self = n.==(n);
+  dynamic equals_null = n.==(null);
+  dynamic null_equals = null.==(n);
+  dynamic not_equals_self = !n.==(n);
+  dynamic not_equals_null = !n.==(null);
+  dynamic null_not_equals = !null.==(n);
+}
+static method main() → dynamic {
+  self::test();
+  new self::SubNullEquality::•().test();
+}
diff --git a/pkg/front_end/testcases/inference/override_equals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/override_equals.dart.strong.transformed.expect
new file mode 100644
index 0000000..5f3bb3f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/override_equals.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class NullEquality extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  @core::override
+  operator ==(core::Object other) → core::Null
+    return null;
+}
+class SubNullEquality extends self::NullEquality {
+  synthetic constructor •() → void
+    : super self::NullEquality::•()
+    ;
+  method test() → void {
+    core::bool super_equals_self = super.{self::NullEquality::==}(this);
+    core::bool super_equals_null = super.{self::NullEquality::==}(null);
+    core::bool super_not_equals_self = !super.{self::NullEquality::==}(this);
+    core::bool super_not_equals_null = !super.{self::NullEquality::==}(null);
+  }
+}
+static method test() → dynamic {
+  self::NullEquality n = new self::NullEquality::•();
+  core::bool equals_self = n.{self::NullEquality::==}(n);
+  core::bool equals_null = n.{self::NullEquality::==}(null);
+  core::bool null_equals = null.{core::Object::==}(n);
+  core::bool not_equals_self = !n.{self::NullEquality::==}(n);
+  core::bool not_equals_null = !n.{self::NullEquality::==}(null);
+  core::bool null_not_equals = !null.{core::Object::==}(n);
+}
+static method main() → dynamic {
+  self::test();
+  new self::SubNullEquality::•().{self::SubNullEquality::test}();
+}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..1edb995
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method optional_toplevel([core::List<core::int> x = const <dynamic>[]]) → void {}
+static method named_toplevel({core::List<core::int> x = const <dynamic>[]}) → void {}
+static method main() → dynamic {
+  function optional_local([core::List<core::int> x = const <dynamic>[]]) → void {}
+  function named_local({core::List<core::int> x = const <dynamic>[]}) → void {}
+  dynamic optional_closure = ([core::List<core::int> x = const <dynamic>[]]) → dynamic {};
+  dynamic name_closure = ({core::List<core::int> x = const <dynamic>[]}) → dynamic {};
+}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..72a4648
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_downwards.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method optional_toplevel([core::List<core::int> x = const <core::int>[]]) → void {}
+static method named_toplevel({core::List<core::int> x = const <core::int>[]}) → void {}
+static method main() → dynamic {
+  function optional_local([core::List<core::int> x = const <core::int>[]]) → void {}
+  function named_local({core::List<core::int> x = const <core::int>[]}) → void {}
+  ([core::List<core::int>]) → core::Null optional_closure = ([core::List<core::int> x = const <core::int>[]]) → core::Null {};
+  ({x: core::List<core::int>}) → core::Null name_closure = ({core::List<core::int> x = const <core::int>[]}) → core::Null {};
+}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..e517d09
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor optional(([self::C::T]) → void func) → void
+    : super core::Object::•() {}
+  constructor named(({x: self::C::T}) → void func) → void
+    : super core::Object::•() {}
+}
+static method optional_toplevel([dynamic x = const <dynamic>[0]]) → void {}
+static method named_toplevel({dynamic x = const <dynamic>[0]}) → void {}
+static method main() → dynamic {
+  function optional_local([dynamic x = const <dynamic>[0]]) → void {}
+  function named_local({dynamic x = const <dynamic>[0]}) → void {}
+  dynamic c_optional_toplevel = new self::C::optional<dynamic>(self::optional_toplevel);
+  dynamic c_named_toplevel = new self::C::named<dynamic>(self::named_toplevel);
+  dynamic c_optional_local = new self::C::optional<dynamic>(optional_local);
+  dynamic c_named_local = new self::C::named<dynamic>(named_local);
+  dynamic c_optional_closure = new self::C::optional<dynamic>(([dynamic x = const <dynamic>[0]]) → dynamic {});
+  dynamic c_named_closure = new self::C::named<dynamic>(({dynamic x = const <dynamic>[0]}) → dynamic {});
+}
diff --git a/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..c8d5b63
--- /dev/null
+++ b/pkg/front_end/testcases/inference/parameter_defaults_upwards.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor optional(([self::C::T]) → void func) → void
+    : super core::Object::•() {}
+  constructor named(({x: self::C::T}) → void func) → void
+    : super core::Object::•() {}
+}
+static method optional_toplevel([dynamic x = const <core::int>[0]]) → void {}
+static method named_toplevel({dynamic x = const <core::int>[0]}) → void {}
+static method main() → dynamic {
+  function optional_local([dynamic x = const <core::int>[0]]) → void {}
+  function named_local({dynamic x = const <core::int>[0]}) → void {}
+  self::C<dynamic> c_optional_toplevel = new self::C::optional<dynamic>(self::optional_toplevel);
+  self::C<dynamic> c_named_toplevel = new self::C::named<dynamic>(self::named_toplevel);
+  self::C<dynamic> c_optional_local = new self::C::optional<dynamic>(optional_local);
+  self::C<dynamic> c_named_local = new self::C::named<dynamic>(named_local);
+  self::C<dynamic> c_optional_closure = new self::C::optional<dynamic>(([dynamic x = const <core::int>[0]]) → core::Null {});
+  self::C<dynamic> c_named_closure = new self::C::named<dynamic>(({dynamic x = const <core::int>[0]}) → core::Null {});
+}
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.direct.transformed.expect
new file mode 100644
index 0000000..e939b9e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → void;
+}
+abstract class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  abstract method bar() → void;
+}
+static method f<T extends self::B>(self::f::T a) → void {
+  if(a is core::String) {
+    a.foo();
+  }
+  if(a is self::C) {
+    a{self::f::T extends self::C}.bar();
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect
new file mode 100644
index 0000000..56d7592
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_bounds.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → void;
+}
+abstract class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  abstract method bar() → void;
+}
+static method f<T extends self::B>(self::f::T a) → void {
+  if(a is core::String) {
+    a.{self::B::foo}();
+  }
+  if(a is self::C) {
+    a{self::f::T extends self::C}.{self::C::bar}();
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.direct.transformed.expect
new file mode 100644
index 0000000..ad926fb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test(core::Object a, core::bool b) → void {
+  if(b && a is core::int) {
+    core::print(a{core::int});
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.strong.transformed.expect
new file mode 100644
index 0000000..ad926fb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promote_from_logical_rhs.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test(core::Object a, core::bool b) → void {
+  if(b && a is core::int) {
+    core::print(a{core::int});
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/promotion_subtype_check.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.direct.transformed.expect
new file mode 100644
index 0000000..cd61e5e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f(core::Object x) → void {
+  if(x is core::int) {
+    if(x{core::int} is core::String) {
+      dynamic y = x{core::int};
+    }
+  }
+}
+static method g(core::int x) → void {
+  if(x is core::String) {
+    dynamic y = x;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/promotion_subtype_check.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.strong.transformed.expect
new file mode 100644
index 0000000..065fb72
--- /dev/null
+++ b/pkg/front_end/testcases/inference/promotion_subtype_check.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f(core::Object x) → void {
+  if(x is core::int) {
+    if(x{core::int} is core::String) {
+      core::int y = x{core::int};
+    }
+  }
+}
+static method g(core::int x) → void {
+  if(x is core::String) {
+    core::int y = x;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.direct.transformed.expect
new file mode 100644
index 0000000..bf0bbce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic a = new self::A::•();
+  self::A b = a;
+  core::print(a.x);
+  core::print(a.x.+(2));
+}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.strong.transformed.expect
new file mode 100644
index 0000000..54fd2f2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::A a = new self::A::•();
+  self::A b = a;
+  core::print(a.{self::A::x});
+  core::print(a.{self::A::x}.{core::num::+}(2));
+}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.direct.transformed.expect
new file mode 100644
index 0000000..bf0bbce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic a = new self::A::•();
+  self::A b = a;
+  core::print(a.x);
+  core::print(a.x.+(2));
+}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.strong.transformed.expect
new file mode 100644
index 0000000..ce0e7d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_to_field_in_class_dynamic_warnings.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic a = new self::A::•();
+  self::A b = a as{TypeError} self::A;
+  core::print(a.x);
+  core::print(a.x.+(2));
+}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.direct.transformed.expect
new file mode 100644
index 0000000..7fd4435
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test5() → dynamic {
+  dynamic a1 = new self::A::•();
+  a1.x = "hi";
+  self::A a2 = new self::A::•();
+  a2.x = "hi";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
new file mode 100644
index 0000000..d0aa09b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 2;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test5() → dynamic {
+  self::A a1 = new self::A::•();
+  a1.{self::A::x} = let final core::String #t1 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:14:57: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  a1. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                                        ^";
+  self::A a2 = new self::A::•();
+  a2.{self::A::x} = let final core::String #t2 = "hi" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/propagate_inference_transitively.dart:17:57: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  a2. /*@target=A::x*/ x = /*error:INVALID_ASSIGNMENT*/ \"hi\";
+                                                        ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.direct.transformed.expect
new file mode 100644
index 0000000..82372f9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 42;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field self::A a = new self::A::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field self::B b = new self::B::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object {
+  field self::C c = new self::C::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  dynamic d1 = new self::D::•();
+  core::print(d1.c.b.a.x);
+  self::D d2 = new self::D::•();
+  core::print(d2.c.b.a.x);
+}
diff --git a/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.strong.transformed.expect
new file mode 100644
index 0000000..b349989
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_inference_transitively2.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int x = 42;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field self::A a = new self::A::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field self::B b = new self::B::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object {
+  field self::C c = new self::C::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → void {
+  self::D d1 = new self::D::•();
+  core::print(d1.{self::D::c}.{self::C::b}.{self::B::a}.{self::A::x});
+  self::D d2 = new self::D::•();
+  core::print(d2.{self::D::c}.{self::C::b}.{self::B::a}.{self::A::x});
+}
diff --git a/pkg/front_end/testcases/inference/propagate_variable_get.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/propagate_variable_get.dart.direct.transformed.expect
new file mode 100644
index 0000000..9bf4a8f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_variable_get.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static method main() → dynamic {
+  dynamic a = 0;
+  dynamic b = a;
+}
diff --git a/pkg/front_end/testcases/inference/propagate_variable_get.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/propagate_variable_get.dart.strong.transformed.expect
new file mode 100644
index 0000000..a5e9d73
--- /dev/null
+++ b/pkg/front_end/testcases/inference/propagate_variable_get.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::int a = 0;
+  core::int b = a;
+}
diff --git a/pkg/front_end/testcases/inference/property_get_toplevel.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/property_get_toplevel.dart.direct.transformed.expect
new file mode 100644
index 0000000..e9e9772
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_get_toplevel.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::int field = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get getter() → core::int
+    return 0;
+  method function() → core::int
+    return 0;
+}
+static field self::C c = new self::C::•();
+static field dynamic function_ref = self::c.function;
+static field dynamic function_ref_list = <dynamic>[self::c.function];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/property_get_toplevel.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/property_get_toplevel.dart.strong.transformed.expect
new file mode 100644
index 0000000..5d01eef
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_get_toplevel.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::int field = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get getter() → core::int
+    return 0;
+  method function() → core::int
+    return 0;
+}
+static field self::C c = new self::C::•();
+static field () → core::int function_ref = self::c.{self::C::function};
+static field core::List<() → core::int> function_ref_list = <() → core::int>[self::c.{self::C::function}];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/property_set.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/property_set.dart.direct.transformed.expect
new file mode 100644
index 0000000..c247031
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set.dart.direct.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  field core::List<self::A::T> x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set y(core::List<self::A::T> value) → void {}
+}
+static method test() → dynamic {
+  self::A<core::int> a_int = new self::A::•<core::int>();
+  self::A<core::Object> a_object = new self::A::•<core::Object>();
+  self::A<dynamic> a_dynamic = new self::A::•<dynamic>();
+  dynamic x_int = a_int.x = <dynamic>[0];
+  dynamic y_int = a_int.y = <dynamic>[0];
+  dynamic x_object = a_object.x = <dynamic>[0];
+  dynamic y_object = a_object.y = <dynamic>[0];
+  dynamic x_dynamic = a_dynamic.x = <dynamic>[0];
+  dynamic y_dynamic = a_dynamic.y = <dynamic>[0];
+  dynamic x_int_explicit = a_int.x = <core::int>[0];
+  dynamic y_int_explicit = a_int.y = <core::int>[0];
+  dynamic x_object_explicit = a_object.x = <core::int>[0];
+  dynamic y_object_explicit = a_object.y = <core::int>[0];
+  dynamic x_dynamic_explicit = a_dynamic.x = <core::int>[0];
+  dynamic y_dynamic_explicit = a_dynamic.y = <core::int>[0];
+  core::List<core::int> x_int_downward = a_int.x = <dynamic>[0];
+  core::List<core::int> y_int_downward = a_int.y = <dynamic>[0];
+  core::List<core::int> x_object_downward = a_object.x = <dynamic>[0];
+  core::List<core::int> y_object_downward = a_object.y = <dynamic>[0];
+  core::List<core::int> x_dynamic_downward = a_dynamic.x = <dynamic>[0];
+  core::List<core::int> y_dynamic_downward = a_dynamic.y = <dynamic>[0];
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/property_set.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/property_set.dart.strong.transformed.expect
new file mode 100644
index 0000000..699d136
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field core::List<self::A::T> x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set y(generic-covariant-impl generic-covariant-interface core::List<self::A::T> value) → void {}
+}
+static method test() → dynamic {
+  self::A<core::int> a_int = new self::A::•<core::int>();
+  self::A<core::Object> a_object = new self::A::•<core::Object>();
+  self::A<dynamic> a_dynamic = new self::A::•<dynamic>();
+  core::List<core::int> x_int = a_int.{self::A::x} = <core::int>[0];
+  core::List<core::int> y_int = a_int.{self::A::y} = <core::int>[0];
+  core::List<core::Object> x_object = a_object.{self::A::x} = <core::Object>[0];
+  core::List<core::Object> y_object = a_object.{self::A::y} = <core::Object>[0];
+  core::List<dynamic> x_dynamic = a_dynamic.{self::A::x} = <dynamic>[0];
+  core::List<dynamic> y_dynamic = a_dynamic.{self::A::y} = <dynamic>[0];
+  core::List<core::int> x_int_explicit = a_int.{self::A::x} = <core::int>[0];
+  core::List<core::int> y_int_explicit = a_int.{self::A::y} = <core::int>[0];
+  core::List<core::int> x_object_explicit = a_object.{self::A::x} = <core::int>[0];
+  core::List<core::int> y_object_explicit = a_object.{self::A::y} = <core::int>[0];
+  core::List<core::int> x_dynamic_explicit = a_dynamic.{self::A::x} = <core::int>[0];
+  core::List<core::int> y_dynamic_explicit = a_dynamic.{self::A::y} = <core::int>[0];
+  core::List<core::int> x_int_downward = a_int.{self::A::x} = <core::int>[0];
+  core::List<core::int> y_int_downward = a_int.{self::A::y} = <core::int>[0];
+  core::List<core::int> x_object_downward = (a_object.{self::A::x} = <core::Object>[0]) as{TypeError} core::List<core::int>;
+  core::List<core::int> y_object_downward = (a_object.{self::A::y} = <core::Object>[0]) as{TypeError} core::List<core::int>;
+  core::List<core::int> x_dynamic_downward = (a_dynamic.{self::A::x} = <dynamic>[0]) as{TypeError} core::List<core::int>;
+  core::List<core::int> y_dynamic_downward = (a_dynamic.{self::A::y} = <dynamic>[0]) as{TypeError} core::List<core::int>;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..48cc6c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(dynamic #synthetic) → void
+    let dynamic _ = null in invalid-expression "pkg/front_end/testcases/inference/property_set_bad_setter.dart:9:16: Error: A setter should have exactly one formal parameter.
+  void set x() {}
+               ^";
+}
+static method f(self::A a) → void {
+  dynamic x = a.x = 0;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..c463475
--- /dev/null
+++ b/pkg/front_end/testcases/inference/property_set_bad_setter.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(dynamic #synthetic) → void
+    let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/property_set_bad_setter.dart:9:16: Error: A setter should have exactly one formal parameter.
+  void set x() {}
+               ^";
+}
+static method f(self::A a) → void {
+  core::int x = a.{self::A::x} = 0;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/recursive_generic_function.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/recursive_generic_function.dart.direct.transformed.expect
new file mode 100644
index 0000000..4af9ac5
--- /dev/null
+++ b/pkg/front_end/testcases/inference/recursive_generic_function.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method _mergeSort<T extends core::Object>((self::_mergeSort::T) → self::_mergeSort::T list, (self::_mergeSort::T, self::_mergeSort::T) → core::int compare, (self::_mergeSort::T) → self::_mergeSort::T target) → void {
+  self::_mergeSort<dynamic>(list, compare, target);
+  self::_mergeSort<dynamic>(list, compare, list);
+  self::_mergeSort<dynamic>(target, compare, target);
+  self::_mergeSort<dynamic>(target, compare, list);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/recursive_generic_function.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/recursive_generic_function.dart.strong.transformed.expect
new file mode 100644
index 0000000..ab23a10
--- /dev/null
+++ b/pkg/front_end/testcases/inference/recursive_generic_function.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method _mergeSort<T extends core::Object>((self::_mergeSort::T) → self::_mergeSort::T list, (self::_mergeSort::T, self::_mergeSort::T) → core::int compare, (self::_mergeSort::T) → self::_mergeSort::T target) → void {
+  self::_mergeSort<self::_mergeSort::T>(list, compare, target);
+  self::_mergeSort<self::_mergeSort::T>(list, compare, list);
+  self::_mergeSort<self::_mergeSort::T>(target, compare, target);
+  self::_mergeSort<self::_mergeSort::T>(target, compare, list);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/reference_to_typedef.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/reference_to_typedef.dart.direct.transformed.expect
new file mode 100644
index 0000000..5d27835
--- /dev/null
+++ b/pkg/front_end/testcases/inference/reference_to_typedef.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library test;
+import self as self;
+
+typedef F = () → void;
+static final field dynamic x = () → void;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/reference_to_typedef.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/reference_to_typedef.dart.strong.transformed.expect
new file mode 100644
index 0000000..2b0c8e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/reference_to_typedef.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+static final field core::Type x = () → void;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.direct.transformed.expect
new file mode 100644
index 0000000..2dcf59c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::num> extends core::Object {
+  field self::C::T a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method op(core::double b) → void {
+    core::double r1 = this.{self::C::a}.+(b);
+    core::double r2 = this.{self::C::a}.-(b);
+    core::double r3 = this.{self::C::a}.*(b);
+    core::double r4 = this.{self::C::a}./(b);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.strong.transformed.expect
new file mode 100644
index 0000000..7a020fb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_double.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::num> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method op(core::double b) → void {
+    core::double r1 = this.{self::C::a}.{core::num::+}(b) as{TypeError} core::double;
+    core::double r2 = this.{self::C::a}.{core::num::-}(b) as{TypeError} core::double;
+    core::double r3 = this.{self::C::a}.{core::num::*}(b) as{TypeError} core::double;
+    core::double r4 = this.{self::C::a}.{core::num::/}(b);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.direct.transformed.expect
new file mode 100644
index 0000000..33580fd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::num> extends core::Object {
+  field self::C::T a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method op(core::int b) → void {
+    self::C::T r1 = this.{self::C::a}.+(b);
+    self::C::T r2 = this.{self::C::a}.-(b);
+    self::C::T r3 = this.{self::C::a}.*(b);
+  }
+  method opEq(core::int b) → void {
+    this.{self::C::a} = this.{self::C::a}.+(b);
+    this.{self::C::a} = this.{self::C::a}.-(b);
+    this.{self::C::a} = this.{self::C::a}.*(b);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.strong.transformed.expect
new file mode 100644
index 0000000..15431c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_int.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::num> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method op(core::int b) → void {
+    self::C::T r1 = this.{self::C::a}.{core::num::+}(b) as{TypeError} self::C::T;
+    self::C::T r2 = this.{self::C::a}.{core::num::-}(b) as{TypeError} self::C::T;
+    self::C::T r3 = this.{self::C::a}.{core::num::*}(b) as{TypeError} self::C::T;
+  }
+  method opEq(core::int b) → void {
+    this.{self::C::a} = this.{self::C::a}.{core::num::+}(b) as{TypeError} self::C::T;
+    this.{self::C::a} = this.{self::C::a}.{core::num::-}(b) as{TypeError} self::C::T;
+    this.{self::C::a} = this.{self::C::a}.{core::num::*}(b) as{TypeError} self::C::T;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.direct.transformed.expect
new file mode 100644
index 0000000..a4422e2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::num> extends core::Object {
+  field self::C::T a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method op(self::C::T b) → void {
+    self::C::T r1 = this.{self::C::a}.+(b);
+    self::C::T r2 = this.{self::C::a}.-(b);
+    self::C::T r3 = this.{self::C::a}.*(b);
+  }
+  method opEq(self::C::T b) → void {
+    this.{self::C::a} = this.{self::C::a}.+(b);
+    this.{self::C::a} = this.{self::C::a}.-(b);
+    this.{self::C::a} = this.{self::C::a}.*(b);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.strong.transformed.expect
new file mode 100644
index 0000000..6410fb3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/refine_binary_expression_type_type_parameter_t_t.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::num> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method op(generic-covariant-impl generic-covariant-interface self::C::T b) → void {
+    self::C::T r1 = this.{self::C::a}.{core::num::+}(b) as{TypeError} self::C::T;
+    self::C::T r2 = this.{self::C::a}.{core::num::-}(b) as{TypeError} self::C::T;
+    self::C::T r3 = this.{self::C::a}.{core::num::*}(b) as{TypeError} self::C::T;
+  }
+  method opEq(generic-covariant-impl generic-covariant-interface self::C::T b) → void {
+    this.{self::C::a} = this.{self::C::a}.{core::num::+}(b) as{TypeError} self::C::T;
+    this.{self::C::a} = this.{self::C::a}.{core::num::-}(b) as{TypeError} self::C::T;
+    this.{self::C::a} = this.{self::C::a}.{core::num::*}(b) as{TypeError} self::C::T;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..7fe0689
--- /dev/null
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int value) → dynamic {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int value) → void {}
+}
+class D extends self::C implements self::I {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set x(dynamic value) → dynamic {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/setter_return_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/setter_return_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..7e46a78
--- /dev/null
+++ b/pkg/front_end/testcases/inference/setter_return_type.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int value) → dynamic {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::int value) → void {}
+}
+class D extends self::C implements self::I {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set x(core::int value) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/simple_literal_bool.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/simple_literal_bool.dart.direct.transformed.expect
new file mode 100644
index 0000000..d23cc34
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_bool.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic a = true;
+static method main() → dynamic {
+  dynamic b = false;
+}
diff --git a/pkg/front_end/testcases/inference/simple_literal_bool.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/simple_literal_bool.dart.strong.transformed.expect
new file mode 100644
index 0000000..de8e757
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_bool.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::bool a = true;
+static method main() → dynamic {
+  core::bool b = false;
+}
diff --git a/pkg/front_end/testcases/inference/simple_literal_double.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/simple_literal_double.dart.direct.transformed.expect
new file mode 100644
index 0000000..1d533d7ce
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_double.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic a = 1.2;
+static method main() → dynamic {
+  dynamic b = 3.4;
+}
diff --git a/pkg/front_end/testcases/inference/simple_literal_double.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/simple_literal_double.dart.strong.transformed.expect
new file mode 100644
index 0000000..726eddf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_double.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::double a = 1.2;
+static method main() → dynamic {
+  core::double b = 3.4;
+}
diff --git a/pkg/front_end/testcases/inference/simple_literal_int.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/simple_literal_int.dart.direct.transformed.expect
new file mode 100644
index 0000000..09ab222
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_int.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic a = 1;
+static method main() → dynamic {
+  dynamic b = 2;
+}
diff --git a/pkg/front_end/testcases/inference/simple_literal_int.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/simple_literal_int.dart.strong.transformed.expect
new file mode 100644
index 0000000..f3562b0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_int.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int a = 1;
+static method main() → dynamic {
+  core::int b = 2;
+}
diff --git a/pkg/front_end/testcases/inference/simple_literal_null.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/simple_literal_null.dart.direct.transformed.expect
new file mode 100644
index 0000000..8afbb2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_null.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic a = null;
+static method main() → dynamic {
+  dynamic b = null;
+}
diff --git a/pkg/front_end/testcases/inference/simple_literal_null.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/simple_literal_null.dart.strong.transformed.expect
new file mode 100644
index 0000000..8afbb2c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/simple_literal_null.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic a = null;
+static method main() → dynamic {
+  dynamic b = null;
+}
diff --git a/pkg/front_end/testcases/inference/static_method_tear_off.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/static_method_tear_off.dart.direct.transformed.expect
new file mode 100644
index 0000000..1b6aeac
--- /dev/null
+++ b/pkg/front_end/testcases/inference/static_method_tear_off.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method f(core::String s) → core::int
+    return null;
+}
+static const field dynamic v = self::C::f;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/static_method_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/static_method_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..f39269c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/static_method_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method f(core::String s) → core::int
+    return null;
+}
+static const field (core::String) → core::int v = self::C::f;
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/string_literal.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/string_literal.dart.direct.transformed.expect
new file mode 100644
index 0000000..741af39
--- /dev/null
+++ b/pkg/front_end/testcases/inference/string_literal.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+
+static field dynamic x = 1;
+static field dynamic a = "aaa";
+static field dynamic b = "b ${self::x} bb";
+static field dynamic c = "c ${self::x} ccccc";
+static method main() → dynamic {
+  dynamic x = 1;
+  dynamic a = "aaa";
+  dynamic b = "b ${x} bb";
+  dynamic c = "c ${x} ccccc";
+}
diff --git a/pkg/front_end/testcases/inference/string_literal.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/string_literal.dart.strong.transformed.expect
new file mode 100644
index 0000000..316edda
--- /dev/null
+++ b/pkg/front_end/testcases/inference/string_literal.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int x = 1;
+static field core::String a = "aaa";
+static field core::String b = "b ${self::x} bb";
+static field core::String c = "c ${self::x} ccccc";
+static method main() → dynamic {
+  core::int x = 1;
+  core::String a = "aaa";
+  core::String b = "b ${x} bb";
+  core::String c = "c ${x} ccccc";
+}
diff --git a/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.direct.transformed.expect
new file mode 100644
index 0000000..1eda6bb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<core::num> x = <dynamic>[0];
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<core::num> y = <dynamic>[0];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.strong.transformed.expect
new file mode 100644
index 0000000..1dd089b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/subexpressions_of_explicitly_typed_fields.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::List<core::num> x = <core::num>[0];
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<core::num> y = <core::num>[0];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_index_set.dart.direct.transformed.expect
new file mode 100644
index 0000000..041e05e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(core::int x, core::String y) → void {}
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  operator []=(core::Object x, core::Object y) → void {}
+  method h() → void {
+    super.{self::B::[]=}(self::f<dynamic>(), self::f<dynamic>());
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect
new file mode 100644
index 0000000..6908392
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(core::int x, core::String y) → void {}
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  operator []=(core::Object x, core::Object y) → void {}
+  method h() → void {
+    super.{self::B::[]=}(self::f<dynamic>() as{TypeError} core::int, self::f<core::String>());
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.direct.transformed.expect
new file mode 100644
index 0000000..cd3af92
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(core::Map<core::int, self::B::T> x, core::List<self::B::T> y) → void {}
+}
+class C<U extends core::Object> extends self::B<asy::Future<self::C::U>> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  operator []=(core::Object x, core::Object y) → void {}
+  method h() → void {
+    super.{self::B::[]=}(self::f<dynamic>(), self::f<dynamic>());
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect
new file mode 100644
index 0000000..a5cd75e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_index_set_substitution.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator []=(generic-covariant-impl generic-covariant-interface core::Map<core::int, self::B::T> x, generic-covariant-impl generic-covariant-interface core::List<self::B::T> y) → void {}
+}
+class C<U extends core::Object> extends self::B<asy::Future<self::C::U>> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  operator []=(generic-covariant-impl core::Object x, generic-covariant-impl core::Object y) → void {}
+  method h() → void {
+    super.{self::B::[]=}(self::f<dynamic>() as{TypeError} core::Map<core::int, asy::Future<self::C::U>>, self::f<core::List<asy::Future<self::C::U>>>());
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_initializer.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_initializer.dart.direct.transformed.expect
new file mode 100644
index 0000000..1d9a2bf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends self::B {
+  constructor •() → void
+    : super self::B::•(self::f<dynamic>())
+    ;
+}
+class B extends core::Object {
+  constructor •(core::int x) → void
+    : super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_initializer.dart.strong.transformed.expect
new file mode 100644
index 0000000..e36e82d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends self::B {
+  constructor •() → void
+    : super self::B::•(self::f<core::int>())
+    ;
+}
+class B extends core::Object {
+  constructor •(core::int x) → void
+    : super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_initializer_substitution.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.direct.transformed.expect
new file mode 100644
index 0000000..e6ba748
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  constructor •(self::B::T t) → void
+    : super core::Object::•()
+    ;
+}
+class C<U extends core::Object> extends self::B<core::List<self::C::U>> {
+  constructor •() → void
+    : super self::B::•(self::f<dynamic>())
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_initializer_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.strong.transformed.expect
new file mode 100644
index 0000000..da5d5a2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_initializer_substitution.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  constructor •(self::B::T t) → void
+    : super core::Object::•()
+    ;
+}
+class C<U extends core::Object> extends self::B<core::List<self::C::U>> {
+  constructor •() → void
+    : super self::B::•(self::f<core::List<self::C::U>>())
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_method_invocation.dart.direct.transformed.expect
new file mode 100644
index 0000000..8cab747
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → core::int
+    return 0;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method g() → void {
+    dynamic x = super.{self::C::f}();
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_method_invocation.dart.strong.transformed.expect
new file mode 100644
index 0000000..ee81a01
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → core::int
+    return 0;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method g() → void {
+    core::int x = super.{self::C::f}();
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.direct.transformed.expect
new file mode 100644
index 0000000..bcfab27
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.direct.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<T extends core::Object> extends self::D<self::E::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method g(self::E<self::B::T> x) → self::D<self::B::T>
+    return null;
+}
+class C<U extends core::Object> extends self::B<asy::Future<self::C::U>> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  method g(core::Object x) → self::E<asy::Future<self::C::U>>
+    return null;
+  method h() → void {
+    dynamic x = super.{self::B::g}(self::f<dynamic>());
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.transformed.expect
new file mode 100644
index 0000000..973b188
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_method_invocation_substitution.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<T extends core::Object> extends self::D<self::E::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method g(generic-covariant-impl generic-covariant-interface self::E<self::B::T> x) → self::D<self::B::T>
+    return null;
+}
+class C<U extends core::Object> extends self::B<asy::Future<self::C::U>> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  method g(generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
+    return null;
+  method h() → void {
+    self::D<asy::Future<self::C::U>> x = super.{self::B::g}(self::f<self::E<asy::Future<self::C::U>>>());
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_get.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_property_get.dart.direct.transformed.expect
new file mode 100644
index 0000000..b924b6f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic x = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method g() → void {
+    dynamic y = super.{self::C::x};
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_get.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_property_get.dart.strong.transformed.expect
new file mode 100644
index 0000000..5b8b0df
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::int x = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method g() → void {
+    core::int y = super.{self::C::x};
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.direct.transformed.expect
new file mode 100644
index 0000000..979a599
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic f = () → dynamic => 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method g() → void {
+    dynamic y = super.{self::C::f}.call();
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.strong.transformed.expect
new file mode 100644
index 0000000..7b98ac9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_function_typed.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field () → core::int f = () → core::int => 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method g() → void {
+    core::int y = super.{self::C::f}.call();
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.direct.transformed.expect
new file mode 100644
index 0000000..6be1419
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.direct.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class CallableClass extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call() → core::int
+    return 0;
+}
+class C extends core::Object {
+  field dynamic f = new self::CallableClass::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method g() → void {
+    dynamic y = super.{self::C::f}.call();
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.strong.transformed.expect
new file mode 100644
index 0000000..8fa0de6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_invoke_implicit_call.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class CallableClass extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call() → core::int
+    return 0;
+}
+class C extends core::Object {
+  field self::CallableClass f = new self::CallableClass::•();
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method g() → void {
+    core::int y = super.{self::C::f}.{self::CallableClass::call}();
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.direct.transformed.expect
new file mode 100644
index 0000000..8ee6c1c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.direct.transformed.expect
@@ -0,0 +1,33 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<T extends core::Object> extends self::D<self::E::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  field self::D<self::B::T> x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<U extends core::Object> extends self::B<asy::Future<self::C::U>> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  get x() → self::E<asy::Future<self::C::U>>
+    return null;
+  set x(core::Object x) → void {}
+  method g() → void {
+    dynamic y = super.{self::B::x};
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.transformed.expect
new file mode 100644
index 0000000..5841a0d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_substitution.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<T extends core::Object> extends self::D<self::E::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::D<self::B::T> x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<U extends core::Object> extends self::B<asy::Future<self::C::U>> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  get x() → self::E<asy::Future<self::C::U>>
+    return null;
+  set x(generic-covariant-impl core::Object x) → void {}
+  method g() → void {
+    self::D<asy::Future<self::C::U>> y = super.{self::B::x};
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.direct.transformed.expect
new file mode 100644
index 0000000..f878cdf
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → core::int
+    return 0;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method g() → void {
+    dynamic y = super.{self::C::f};
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.strong.transformed.expect
new file mode 100644
index 0000000..71fd364
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_get_tearoff.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → core::int
+    return 0;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method g() → void {
+    () → core::int y = super.{self::C::f};
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.direct.transformed.expect
new file mode 100644
index 0000000..f4bec43
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.direct.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<T extends core::Object> extends self::D<self::E::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  field self::D<self::B::T> x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<U extends core::Object> extends self::B<asy::Future<self::C::U>> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  get x() → self::E<asy::Future<self::C::U>>
+    return null;
+  set x(core::Object x) → void {}
+  method g() → void {
+    super.{self::B::x} = self::f<dynamic>();
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.transformed.expect
new file mode 100644
index 0000000..3103ff0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/super_property_set_substitution.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<T extends core::Object> extends self::D<self::E::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::D<self::B::T> x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<U extends core::Object> extends self::B<asy::Future<self::C::U>> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  get x() → self::E<asy::Future<self::C::U>>
+    return null;
+  set x(generic-covariant-impl core::Object x) → void {}
+  method g() → void {
+    super.{self::B::x} = self::f<self::D<asy::Future<self::C::U>>>();
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/switch_continue.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/switch_continue.dart.direct.transformed.expect
new file mode 100644
index 0000000..9a02ec6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/switch_continue.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test(core::int x, () → void f) → void {
+  #L1:
+  switch(x) {
+    #L2:
+    case 0:
+      {
+        f.call();
+        continue #L3;
+      }
+    #L3:
+    case 1:
+      {
+        f.call();
+        break #L1;
+      }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/switch_continue.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/switch_continue.dart.strong.transformed.expect
new file mode 100644
index 0000000..9a02ec6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/switch_continue.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test(core::int x, () → void f) → void {
+  #L1:
+  switch(x) {
+    #L2:
+    case 0:
+      {
+        f.call();
+        continue #L3;
+      }
+    #L3:
+    case 1:
+      {
+        f.call();
+        break #L1;
+      }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/symbol_literal.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/symbol_literal.dart.direct.transformed.expect
new file mode 100644
index 0000000..88a58fe
--- /dev/null
+++ b/pkg/front_end/testcases/inference/symbol_literal.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static method test() → void {
+  dynamic x = #foo;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/symbol_literal.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/symbol_literal.dart.strong.transformed.expect
new file mode 100644
index 0000000..ea090c7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/symbol_literal.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test() → void {
+  core::Symbol x = #foo;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/this_reference.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/this_reference.dart.direct.transformed.expect
new file mode 100644
index 0000000..b04ed9d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/this_reference.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → void {
+    dynamic x = this;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/this_reference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/this_reference.dart.strong.transformed.expect
new file mode 100644
index 0000000..2c721a1
--- /dev/null
+++ b/pkg/front_end/testcases/inference/this_reference.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → void {
+    self::C<self::C::T> x = this;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.direct.transformed.expect
new file mode 100644
index 0000000..5ffcce0
--- /dev/null
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.direct.transformed.expect
@@ -0,0 +1,131 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+typedef IntToInt = (core::int) → core::int;
+static method a() → (core::int) → core::int {
+  return (dynamic x) → dynamic => x;
+}
+static method b() → asy::Future<(core::int) → core::int> /* originally async */ {
+  final asy::Completer<(core::int) → core::int> :completer = asy::Completer::sync<(core::int) → core::int>();
+  asy::FutureOr<(core::int) → core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = (dynamic x) → dynamic => x;
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method c() → core::Iterable<(core::int) → core::int> /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<(core::int) → core::int> :iterator) → core::bool yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = (dynamic x) → dynamic => x;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<(core::int) → core::int>(:sync_op);
+}
+static method d() → core::Iterable<(core::int) → core::int> /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<(core::int) → core::int> :iterator) → core::bool yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_yieldEachIterable} = <dynamic>[(dynamic x) → dynamic => x];
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<(core::int) → core::int>(:sync_op);
+}
+static method e() → asy::Stream<(core::int) → core::int> /* originally async* */ {
+  asy::_AsyncStarStreamController<(core::int) → core::int> :controller;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L2:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}((dynamic x) → dynamic => x))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<(core::int) → core::int>(:async_op);
+  return :controller.{asy::_AsyncStarStreamController::stream};
+}
+static method f() → asy::Stream<(core::int) → core::int> /* originally async* */ {
+  asy::_AsyncStarStreamController<(core::int) → core::int> :controller;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L3:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(asy::Stream::fromIterable<dynamic>(<dynamic>[(dynamic x) → dynamic => x])))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<(core::int) → core::int>(:async_op);
+  return :controller.{asy::_AsyncStarStreamController::stream};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
new file mode 100644
index 0000000..a683365
--- /dev/null
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
@@ -0,0 +1,134 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+typedef IntToInt = (core::int) → core::int;
+static method a() → (core::int) → core::int {
+  return (core::int x) → core::int => x;
+}
+static method b() → asy::Future<(core::int) → core::int> /* originally async */ {
+  final asy::Completer<(core::int) → core::int> :completer = asy::Completer::sync<(core::int) → core::int>();
+  asy::FutureOr<(core::int) → core::int> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        :return_value = let final (dynamic) → dynamic #t1 = (dynamic x) → dynamic => x in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:34: Error: A value of type '(dynamic) \u8594 dynamic' can't be assigned to a variable of type 'dart.async::FutureOr<(dart.core::int) \u8594 dart.core::int>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.async::FutureOr<(dart.core::int) \u8594 dart.core::int>'.
+  return /*@returnType=dynamic*/ (/*@type=dynamic*/ x) => x;
+                                 ^";
+        break #L1;
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method c() → core::Iterable<(core::int) → core::int> /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<(core::int) → core::int> :iterator) → core::bool yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_current} = (core::int x) → core::int => x;
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<(core::int) → core::int>(:sync_op);
+}
+static method d() → core::Iterable<(core::int) → core::int> /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<(core::int) → core::int> :iterator) → core::bool yielding {
+    {
+      {
+        :iterator.{core::_SyncIterator::_yieldEachIterable} = <(core::int) → core::int>[(core::int x) → core::int => x];
+        [yield] true;
+      }
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<(core::int) → core::int>(:sync_op);
+}
+static method e() → asy::Stream<(core::int) → core::int> /* originally async* */ {
+  asy::_AsyncStarStreamController<(core::int) → core::int> :controller;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L2:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::add}((core::int x) → core::int => x))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<(core::int) → core::int>(:async_op);
+  return :controller.{asy::_AsyncStarStreamController::stream};
+}
+static method f() → asy::Stream<(core::int) → core::int> /* originally async* */ {
+  asy::_AsyncStarStreamController<(core::int) → core::int> :controller;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try
+      try {
+        #L3:
+        {
+          if(:controller.{asy::_AsyncStarStreamController::addStream}(asy::Stream::fromIterable<(core::int) → core::int>(<(core::int) → core::int>[(core::int x) → core::int => x])))
+            return null;
+          else
+            [yield] null;
+        }
+        return;
+      }
+      on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+        :controller.{asy::_AsyncStarStreamController::addError}(:exception, :stack_trace);
+      }
+    finally {
+      :controller.{asy::_AsyncStarStreamController::close}();
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  :controller = new asy::_AsyncStarStreamController::•<(core::int) → core::int>(:async_op);
+  return :controller.{asy::_AsyncStarStreamController::stream};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.direct.transformed.expect
new file mode 100644
index 0000000..0949789
--- /dev/null
+++ b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic i = 0;
+static method main() → dynamic {
+  dynamic j = self::i;
+}
diff --git a/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.strong.transformed.expect
new file mode 100644
index 0000000..2d6359d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/toplevel_inference_toplevel_var.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int i = 0;
+static method main() → dynamic {
+  core::int j = self::i;
+}
diff --git a/pkg/front_end/testcases/inference/try_catch.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/try_catch.dart.direct.transformed.expect
new file mode 100644
index 0000000..b39e7c9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch.dart.direct.transformed.expect
@@ -0,0 +1,40 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test(() → void f) → void {
+  try {
+    dynamic x = 0;
+    f.call();
+  }
+  on self::C catch(no-exception-var) {
+    dynamic x = 0;
+  }
+  on self::D catch(final self::D x) {
+    dynamic x2 = x;
+  }
+  on self::E catch(final self::E x, final core::StackTrace y) {
+    dynamic x2 = x;
+    dynamic y2 = y;
+  }
+  on dynamic catch(final dynamic x, final core::StackTrace y) {
+    dynamic x2 = x;
+    dynamic y2 = y;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/try_catch.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/try_catch.dart.strong.transformed.expect
new file mode 100644
index 0000000..98944f71
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch.dart.strong.transformed.expect
@@ -0,0 +1,40 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test(() → void f) → void {
+  try {
+    core::int x = 0;
+    f.call();
+  }
+  on self::C catch(no-exception-var) {
+    core::int x = 0;
+  }
+  on self::D catch(final self::D x) {
+    self::D x2 = x;
+  }
+  on self::E catch(final self::E x, final core::StackTrace y) {
+    self::E x2 = x;
+    core::StackTrace y2 = y;
+  }
+  on dynamic catch(final dynamic x, final core::StackTrace y) {
+    dynamic x2 = x;
+    core::StackTrace y2 = y;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/try_catch_finally.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/try_catch_finally.dart.direct.transformed.expect
new file mode 100644
index 0000000..f99d7ff
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_finally.dart.direct.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test(() → void f) → void {
+  try
+    try {
+      dynamic x = 0;
+      f.call();
+    }
+    on self::C catch(no-exception-var) {
+      dynamic x = 0;
+    }
+    on self::D catch(final self::D x) {
+      dynamic x2 = x;
+    }
+    on self::E catch(final self::E x, final core::StackTrace y) {
+      dynamic x2 = x;
+      dynamic y2 = y;
+    }
+    on dynamic catch(final dynamic x, final core::StackTrace y) {
+      dynamic x2 = x;
+      dynamic y2 = y;
+    }
+  finally {
+    dynamic x = 0;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/try_catch_finally.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/try_catch_finally.dart.strong.transformed.expect
new file mode 100644
index 0000000..b68e248
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_finally.dart.strong.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method test(() → void f) → void {
+  try
+    try {
+      core::int x = 0;
+      f.call();
+    }
+    on self::C catch(no-exception-var) {
+      core::int x = 0;
+    }
+    on self::D catch(final self::D x) {
+      self::D x2 = x;
+    }
+    on self::E catch(final self::E x, final core::StackTrace y) {
+      self::E x2 = x;
+      core::StackTrace y2 = y;
+    }
+    on dynamic catch(final dynamic x, final core::StackTrace y) {
+      dynamic x2 = x;
+      core::StackTrace y2 = y;
+    }
+  finally {
+    core::int x = 0;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/try_catch_promotion.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/try_catch_promotion.dart.direct.transformed.expect
new file mode 100644
index 0000000..6d36f68
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_promotion.dart.direct.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+class E extends core::StackTrace {
+  synthetic constructor •() → void
+    : super core::StackTrace::•()
+    ;
+}
+static method test(() → void f) → void {
+  try {
+    f.call();
+  }
+  on self::C catch(final self::C x, final core::StackTrace y) {
+    dynamic x1 = x;
+    dynamic y1 = y;
+    if(x is self::D) {
+      dynamic x2 = x{self::D};
+    }
+    if(y is self::E) {
+      dynamic y2 = y{self::E};
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/try_catch_promotion.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/try_catch_promotion.dart.strong.transformed.expect
new file mode 100644
index 0000000..0f2ef25
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_catch_promotion.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+class E extends core::StackTrace {
+  synthetic constructor •() → void
+    : super core::StackTrace::•()
+    ;
+}
+static method test(() → void f) → void {
+  try {
+    f.call();
+  }
+  on self::C catch(final self::C x, final core::StackTrace y) {
+    self::C x1 = x;
+    core::StackTrace y1 = y;
+    if(x is self::D) {
+      self::D x2 = x{self::D};
+    }
+    if(y is self::E) {
+      self::E y2 = y{self::E};
+    }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/try_finally.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/try_finally.dart.direct.transformed.expect
new file mode 100644
index 0000000..8af676e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_finally.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+
+static method test(() → void f) → void {
+  try {
+    dynamic x = 0;
+    f.call();
+  }
+  finally {
+    dynamic x = 0;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/try_finally.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/try_finally.dart.strong.transformed.expect
new file mode 100644
index 0000000..d84fe32
--- /dev/null
+++ b/pkg/front_end/testcases/inference/try_finally.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method test(() → void f) → void {
+  try {
+    core::int x = 0;
+    f.call();
+  }
+  finally {
+    core::int x = 0;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/type_cast.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/type_cast.dart.direct.transformed.expect
new file mode 100644
index 0000000..92d88c6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_cast.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::Object> extends self::A<self::B::T> {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  method foo() → dynamic {}
+}
+static field self::A<core::num> a = new self::B::•<core::int>();
+static field dynamic b = self::a as self::B<core::int>;
+static method main() → dynamic {
+  self::A<core::num> a = new self::B::•<core::int>();
+  dynamic b = a as self::B<core::int>;
+}
diff --git a/pkg/front_end/testcases/inference/type_cast.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/type_cast.dart.strong.transformed.expect
new file mode 100644
index 0000000..2418fa8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_cast.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::Object> extends self::A<self::B::T> {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  method foo() → dynamic {}
+}
+static field self::A<core::num> a = new self::B::•<core::int>();
+static field self::B<core::int> b = self::a as self::B<core::int>;
+static method main() → dynamic {
+  self::A<core::num> a = new self::B::•<core::int>();
+  self::B<core::int> b = a as self::B<core::int>;
+}
diff --git a/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.direct.transformed.expect
new file mode 100644
index 0000000..ed2a536
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef FunctionReturningInt = () → core::int;
+static method main() → dynamic {
+  function f() → core::num
+    return 0;
+  if(f is () → core::int) {
+    f;
+  }
+}
diff --git a/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.strong.transformed.expect
new file mode 100644
index 0000000..ed2a536
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_ignores_local_functions.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef FunctionReturningInt = () → core::int;
+static method main() → dynamic {
+  function f() → core::num
+    return 0;
+  if(f is () → core::int) {
+    f;
+  }
+}
diff --git a/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.direct.transformed.expect
new file mode 100644
index 0000000..c1b36d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f(core::Object x) → void {
+  if(!(x is core::int) && !(x is core::String)) {
+    core::print(x);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.strong.transformed.expect
new file mode 100644
index 0000000..c1b36d9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_not_and_not.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f(core::Object x) → void {
+  if(!(x is core::int) && !(x is core::String)) {
+    core::print(x);
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/type_promotion_simple.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_simple.dart.direct.transformed.expect
new file mode 100644
index 0000000..d61ebea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_simple.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::num n = null;
+  if(n is core::int) {
+    dynamic i = n{core::int};
+  }
+}
diff --git a/pkg/front_end/testcases/inference/type_promotion_simple.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_simple.dart.strong.transformed.expect
new file mode 100644
index 0000000..23b3aad
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_simple.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::num n = null;
+  if(n is core::int) {
+    core::int i = n{core::int};
+  }
+}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.direct.transformed.expect
new file mode 100644
index 0000000..b17518b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::num n = null;
+  if(n is core::int) {
+    dynamic i = n;
+    () → dynamic {
+      n;
+    };
+  }
+  n = null;
+}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.transformed.expect
new file mode 100644
index 0000000..c9ff1d7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_access_in_a_closure.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::num n = null;
+  if(n is core::int) {
+    core::num i = n;
+    () → core::Null {
+      n;
+    };
+  }
+  n = null;
+}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.direct.transformed.expect
new file mode 100644
index 0000000..e514dc9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::num n = null;
+  if(n is core::int) {
+    dynamic i = n;
+    n = null;
+  }
+}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.strong.transformed.expect
new file mode 100644
index 0000000..8c76b1a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_assignment_in_scope.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::num n = null;
+  if(n is core::int) {
+    core::num i = n;
+    n = null;
+  }
+}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.direct.transformed.expect
new file mode 100644
index 0000000..94f5eec
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::num n = null;
+  if(n is core::int) {
+    dynamic i = n;
+  }
+  () → dynamic {
+    n = null;
+  };
+}
diff --git a/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.transformed.expect
new file mode 100644
index 0000000..8e7c6a9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/type_promotion_stopped_by_mutation_in_a_closure.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::num n = null;
+  if(n is core::int) {
+    core::num i = n;
+  }
+  () → core::Null {
+    n = null;
+  };
+}
diff --git a/pkg/front_end/testcases/inference/unresolved_super.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unresolved_super.dart.direct.transformed.expect
new file mode 100644
index 0000000..42d105e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unresolved_super.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    dynamic v1 = super.foo(self::f<dynamic>());
+    dynamic v2 = super.bar;
+    dynamic v3 = super.[](0);
+    dynamic v4 = super.bar = self::f<dynamic>();
+    dynamic v5 = let final dynamic #t1 = 0 in let final dynamic #t2 = self::f<dynamic>() in let final dynamic #t3 = super.[]=(#t1, #t2) in #t2;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.direct.transformed.expect
new file mode 100644
index 0000000..b2b95bc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static method main() → dynamic {
+  dynamic v = ((dynamic x) → dynamic => 1.0).call(() → dynamic {
+    return 1;
+  });
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.strong.transformed.expect
new file mode 100644
index 0000000..99a6a26
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_closure_call.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::double v = ((dynamic x) → core::double => 1.0).call(() → core::int {
+    return 1;
+  });
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..ea9c98e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor •(() → self::C::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic v = new self::C::•<dynamic>(() → dynamic {
+  return 1;
+});
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..e19dd93
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_dynamic_param.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor •(() → self::C::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field self::C<dynamic> v = new self::C::•<dynamic>(() → core::int {
+  return 1;
+});
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..2f5725e
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor •(() → self::C::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic v = new self::C::•<core::int>(() → dynamic {
+  return 1;
+});
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..cdef38d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_explicit_type_param.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor •(() → self::C::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field self::C<core::int> v = new self::C::•<core::int>(() → core::int {
+  return 1;
+});
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..ab67a68
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor •(() → self::C::T x) → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic v = new self::C::•<dynamic>(() → dynamic {
+    return 1;
+  });
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..9377cb7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_implicit_type_param.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  constructor •(() → self::C::T x) → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::C<core::int> v = new self::C::•<core::int>(() → core::int {
+    return 1;
+  });
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..3f1628c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •(() → dynamic x) → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic v = new self::C::•(() → dynamic {
+  return 1;
+});
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..eee08a4
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_constructor_call_no_type_param.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •(() → dynamic x) → void
+    : super core::Object::•()
+    ;
+}
+static field self::C v = new self::C::•(() → core::int {
+  return 1;
+});
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..987511d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic v = self::f<dynamic>(() → dynamic {
+  return 1;
+});
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..757a833
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<dynamic> v = self::f<dynamic>(() → core::int {
+  return 1;
+});
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..4965d22
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic v = self::f<core::int>(() → dynamic {
+  return 1;
+});
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..4242dc9
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_explicit_type_param.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> v = self::f<core::int>(() → core::int {
+  return 1;
+});
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..89fc3e2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  dynamic v = self::f<dynamic>(() → dynamic {
+    return 1;
+  });
+}
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..27f92d8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::List<core::int> v = self::f<core::int>(() → core::int {
+    return 1;
+  });
+}
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.direct.transformed.expect
new file mode 100644
index 0000000..5d7db44
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  dynamic v = self::f.call(() → dynamic {
+    return 1;
+  });
+}
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.strong.transformed.expect
new file mode 100644
index 0000000..d78578d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_implicit_type_param_via_expr.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::List<core::int> v = self::f.call<core::int>(() → core::int {
+    return 1;
+  });
+}
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..ffbb143
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  dynamic v = self::f(() → dynamic {
+    return 1;
+  });
+}
+static method f(dynamic x) → core::double
+  return 1.0;
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..1094b0c
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::double v = self::f(() → core::int {
+    return 1;
+  });
+}
+static method f(dynamic x) → core::double
+  return 1.0;
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.direct.transformed.expect
new file mode 100644
index 0000000..5a76d33
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  dynamic v = self::f.call(() → dynamic {
+    return 1;
+  });
+}
+static method f(dynamic x) → core::double
+  return 1.0;
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.strong.transformed.expect
new file mode 100644
index 0000000..2d6d957
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_function_call_no_type_param_via_expr.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::double v = self::f.call(() → core::int {
+    return 1;
+  });
+}
+static method f(dynamic x) → core::double
+  return 1.0;
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.direct.transformed.expect
new file mode 100644
index 0000000..52a9a4a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static method main() → dynamic {
+  dynamic v = <dynamic>[() → dynamic {
+    return 1;
+  }];
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.strong.transformed.expect
new file mode 100644
index 0000000..6fd611f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_dynamic.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::List<dynamic> v = <dynamic>[() → core::int {
+    return 1;
+  }];
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.direct.transformed.expect
new file mode 100644
index 0000000..98cc09d
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → core::int;
+static method main() → dynamic {
+  dynamic v = <() → core::int>[() → dynamic {
+    return 1;
+  }];
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.strong.transformed.expect
new file mode 100644
index 0000000..20689bc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_typed.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → core::int;
+static method main() → dynamic {
+  core::List<() → core::int> v = <() → core::int>[() → core::int {
+    return 1;
+  }];
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.direct.transformed.expect
new file mode 100644
index 0000000..52a9a4a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static method main() → dynamic {
+  dynamic v = <dynamic>[() → dynamic {
+    return 1;
+  }];
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.strong.transformed.expect
new file mode 100644
index 0000000..486e1f3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_list_untyped.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::List<() → core::int> v = <() → core::int>[() → core::int {
+    return 1;
+  }];
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.direct.transformed.expect
new file mode 100644
index 0000000..92e6fc6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  dynamic v = <core::int, dynamic>{1: () → dynamic {
+    return 1;
+  }};
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.strong.transformed.expect
new file mode 100644
index 0000000..e93a072
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_dynamic.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::Map<core::int, dynamic> v = <core::int, dynamic>{1: () → core::int {
+    return 1;
+  }};
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.direct.transformed.expect
new file mode 100644
index 0000000..9d859cc
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → core::int;
+static method main() → dynamic {
+  dynamic v = <core::int, () → core::int>{1: () → dynamic {
+    return 1;
+  }};
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.strong.transformed.expect
new file mode 100644
index 0000000..2824231
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_typed.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → core::int;
+static method main() → dynamic {
+  core::Map<core::int, () → core::int> v = <core::int, () → core::int>{1: () → core::int {
+    return 1;
+  }};
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.direct.transformed.expect
new file mode 100644
index 0000000..c3ba8bd
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+
+static method main() → dynamic {
+  dynamic v = <dynamic, dynamic>{1: () → dynamic {
+    return 1;
+  }};
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.strong.transformed.expect
new file mode 100644
index 0000000..20d29e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_in_map_untyped.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::Map<core::int, () → core::int> v = <core::int, () → core::int>{1: () → core::int {
+    return 1;
+  }};
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..94926cb
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>(() → self::C::f::T g) → core::List<self::C::f::T>
+    return <self::C::f::T>[g.call()];
+}
+static method main() → dynamic {
+  dynamic v = new self::C::•().f<dynamic>(() → dynamic {
+    return 1;
+  });
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..453c72f
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_dynamic_param.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>(() → self::C::f::T g) → core::List<self::C::f::T>
+    return <self::C::f::T>[g.call()];
+}
+static method main() → dynamic {
+  core::List<dynamic> v = new self::C::•().{self::C::f}<dynamic>(() → core::int {
+    return 1;
+  });
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..601a1ea
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>(() → self::C::f::T g) → core::List<self::C::f::T>
+    return <self::C::f::T>[g.call()];
+}
+static method main() → dynamic {
+  dynamic v = new self::C::•().f<core::int>(() → dynamic {
+    return 1;
+  });
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..2cb1a2a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_explicit_type_param.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>(() → self::C::f::T g) → core::List<self::C::f::T>
+    return <self::C::f::T>[g.call()];
+}
+static method main() → dynamic {
+  core::List<core::int> v = new self::C::•().{self::C::f}<core::int>(() → core::int {
+    return 1;
+  });
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..46c4204
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>(() → self::C::f::T g) → core::List<self::C::f::T>
+    return <self::C::f::T>[g.call()];
+}
+static method main() → dynamic {
+  dynamic v = new self::C::•().f(() → dynamic {
+    return 1;
+  });
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..2cb1a2a
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_implicit_type_param.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>(() → self::C::f::T g) → core::List<self::C::f::T>
+    return <self::C::f::T>[g.call()];
+}
+static method main() → dynamic {
+  core::List<core::int> v = new self::C::•().{self::C::f}<core::int>(() → core::int {
+    return 1;
+  });
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..65b6c5b
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(dynamic x) → core::double
+    return 1.0;
+}
+static field dynamic v = new self::C::•().f(() → dynamic {
+  return 1;
+});
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..a24ce84
--- /dev/null
+++ b/pkg/front_end/testcases/inference/unsafe_block_closure_inference_method_call_no_type_param.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(dynamic x) → core::double
+    return 1.0;
+}
+static field core::double v = new self::C::•().{self::C::f}(() → core::int {
+  return 1;
+});
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.direct.transformed.expect
new file mode 100644
index 0000000..7aabcb2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic x = self::run<dynamic>(self::printRunning);
+static method run<T extends core::Object>(() → self::run::T f) → self::run::T {
+  core::print("running");
+  dynamic t = f.call();
+  core::print("done running");
+  return t;
+}
+static method printRunning() → void {
+  core::print("running");
+}
+static method main() → dynamic {
+  function printRunning() → void {
+    core::print("running");
+  }
+  dynamic x = self::run<dynamic>(printRunning);
+  dynamic y = self::run<dynamic>(printRunning);
+  x = 123;
+  x = "hi";
+  y = 123;
+  y = "hi";
+}
diff --git a/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.strong.transformed.expect
new file mode 100644
index 0000000..0fdc0e3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/void_return_type_subtypes_dynamic.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic x = self::run<dynamic>(self::printRunning);
+static method run<T extends core::Object>(() → self::run::T f) → self::run::T {
+  core::print("running");
+  self::run::T t = f.call();
+  core::print("done running");
+  return t;
+}
+static method printRunning() → void {
+  core::print("running");
+}
+static method main() → dynamic {
+  function printRunning() → void {
+    core::print("running");
+  }
+  dynamic x = self::run<dynamic>(printRunning);
+  void y = self::run<void>(printRunning);
+  x = 123;
+  x = "hi";
+  y = 123;
+  y = "hi";
+}
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.direct.transformed.expect
new file mode 100644
index 0000000..16e4209
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<U extends core::Object, V extends core::Object> = (U) → V;
+class Foo<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get v1() → self::Bar<self::Foo::T>
+    return const self::Bar::•<dynamic>();
+  get v2() → self::Bar<core::List<self::Foo::T>>
+    return const self::Bar::•<dynamic>();
+  get v3() → self::Bar<(self::Foo::T) → self::Foo::T>
+    return const self::Bar::•<dynamic>();
+  get v4() → self::Bar<((self::Foo::T) → self::Foo::T) → self::Foo::T>
+    return const self::Bar::•<dynamic>();
+  get v5() → core::List<self::Foo::T>
+    return const <dynamic>[];
+  get v6() → core::List<(self::Foo::T) → self::Foo::T>
+    return const <dynamic>[];
+  get v7() → core::Map<self::Foo::T, self::Foo::T>
+    return const <dynamic, dynamic>{};
+  get v8() → core::Map<(self::Foo::T) → self::Foo::T, self::Foo::T>
+    return const <dynamic, dynamic>{};
+  get v9() → core::Map<self::Foo::T, (self::Foo::T) → self::Foo::T>
+    return const <dynamic, dynamic>{};
+}
+class Bar<T extends core::Object> extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect
new file mode 100644
index 0000000..ae42957
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/const_invocation.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<U extends core::Object, V extends core::Object> = (U) → V;
+class Foo<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get v1() → self::Bar<self::Foo::T>
+    return const self::Bar::•<core::Null>();
+  get v2() → self::Bar<core::List<self::Foo::T>>
+    return const self::Bar::•<core::List<core::Null>>();
+  generic-contravariant get v3() → self::Bar<(self::Foo::T) → self::Foo::T>
+    return const self::Bar::•<(core::Object) → core::Null>();
+  generic-contravariant get v4() → self::Bar<((self::Foo::T) → self::Foo::T) → self::Foo::T>
+    return const self::Bar::•<((core::Null) → core::Object) → core::Null>();
+  get v5() → core::List<self::Foo::T>
+    return const <core::Null>[];
+  generic-contravariant get v6() → core::List<(self::Foo::T) → self::Foo::T>
+    return const <(core::Object) → core::Null>[];
+  get v7() → core::Map<self::Foo::T, self::Foo::T>
+    return const <core::Null, core::Null>{};
+  generic-contravariant get v8() → core::Map<(self::Foo::T) → self::Foo::T, self::Foo::T>
+    return const <(core::Object) → core::Null, core::Null>{};
+  generic-contravariant get v9() → core::Map<self::Foo::T, (self::Foo::T) → self::Foo::T>
+    return const <core::Null, (core::Object) → core::Null>{};
+}
+class Bar<T extends core::Object> extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.direct.transformed.expect
new file mode 100644
index 0000000..2e54afa
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>(self::A::f::T t) → self::A::f::T
+    return t;
+  method g(dynamic i) → core::int
+    return 0;
+}
+static field dynamic a = new self::A::•();
+static field dynamic b = () → dynamic => self::a.f(self::c);
+static field dynamic c = () → dynamic => self::a.f(self::b);
+static field dynamic d = () → dynamic => self::a.f(self::e);
+static field dynamic e = () → dynamic => self::a.g(self::d);
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
new file mode 100644
index 0000000..b23bd77
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<T extends core::Object>(self::A::f::T t) → self::A::f::T
+    return t;
+  method g(dynamic i) → core::int
+    return 0;
+}
+static field self::A a = new self::A::•();
+static field dynamic b = () → dynamic => self::a.{self::A::f}<dynamic>(self::c);
+static field dynamic c = () → dynamic => self::a.{self::A::f}<dynamic>(self::b);
+static field () → () → core::int d = () → () → core::int => self::a.{self::A::f}<() → core::int>(self::e);
+static field () → core::int e = () → core::int => self::a.{self::A::g}(self::d);
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:20:67: Error: Can't infer the type of 'c': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ c = /*@returnType=dynamic*/ () =>
+                                                                  ^", "pkg/front_end/testcases/inference_new/dependency_only_if_generic_method.dart:18:67: Error: Can't infer the type of 'b': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = /*@returnType=dynamic*/ () =>
+                                                                  ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.direct.transformed.expect
new file mode 100644
index 0000000..24f6d1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int intValue = 0;
+static field core::num numValue = 0;
+static field core::double doubleValue = 0.0;
+static field dynamic a = () → dynamic => self::intValue.+(self::b);
+static field dynamic b = self::a.call();
+static field dynamic c = () → dynamic => self::numValue.+(self::d);
+static field dynamic d = self::c.call();
+static field dynamic e = () → dynamic => self::doubleValue.+(self::f);
+static field dynamic f = self::e.call();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect
new file mode 100644
index 0000000..8c0e3f3
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int intValue = 0;
+static field core::num numValue = 0;
+static field core::double doubleValue = 0.0;
+static field dynamic a = () → core::num => self::intValue.{core::num::+}(self::b as{TypeError} core::num);
+static field dynamic b = self::a.call();
+static field () → core::num c = () → core::num => self::numValue.{core::num::+}(self::d);
+static field core::num d = self::c.call();
+static field () → core::double e = () → core::double => self::doubleValue.{core::double::+}(self::f);
+static field core::double f = self::e.call();
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:17:67: Error: Can't infer the type of 'b': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = a();
+                                                                  ^", "pkg/front_end/testcases/inference_new/dependency_only_if_overloaded.dart:15:67: Error: Can't infer the type of 'a': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ a = /*@returnType=num*/ () =>
+                                                                  ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/do_loop.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/do_loop.dart.direct.transformed.expect
new file mode 100644
index 0000000..8d9986c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/do_loop.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  do {
+    dynamic x = 0;
+  }
+  while (self::f<dynamic>())
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/do_loop.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/do_loop.dart.strong.transformed.expect
new file mode 100644
index 0000000..9262769
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/do_loop.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  do {
+    core::int x = 0;
+  }
+  while (self::f<core::bool>())
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.direct.transformed.expect
new file mode 100644
index 0000000..e86775a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field self::B<core::int> b = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  constructor •(self::B::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic t3 = <dynamic>[new self::B::•<dynamic>(3)];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.strong.transformed.expect
new file mode 100644
index 0000000..019ae1b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field self::B<core::int> b = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  constructor •(self::B::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<self::B<core::int>> t3 = <self::B<core::int>>[new self::B::•<core::int>(3)];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.direct.transformed.expect
new file mode 100644
index 0000000..ca47657
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  constructor •(self::A::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic t2 = <dynamic>[new self::A::•<dynamic>(2)];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.strong.transformed.expect
new file mode 100644
index 0000000..115862f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/downwards_inference_inside_top_level_2.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  constructor •(self::A::T x) → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<self::A<core::int>> t2 = <self::A<core::int>>[new self::A::•<core::int>(2)];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.direct.transformed.expect
new file mode 100644
index 0000000..ae0c7e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic x = () → dynamic => new self::B::•().x;
+  field dynamic y = () → dynamic => new self::B::•().x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  field dynamic x = null;
+  field dynamic y = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
new file mode 100644
index 0000000..b5ea678
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/field_inference_circularity.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic x = () → dynamic => new self::B::•().{self::B::x};
+  field () → dynamic y = () → dynamic => new self::B::•().{self::B::x};
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  field dynamic x = null;
+  field () → dynamic y = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference_new/field_inference_circularity.dart:12:69: Error: Can't infer the type of 'x': circularity found during type inference.
+Specify the type explicitly.
+  var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
+                                                                    ^", "pkg/front_end/testcases/inference_new/field_inference_circularity.dart:19:69: Error: Can't infer the type of 'x': circularity found during type inference.
+Specify the type explicitly.
+  var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x;
+                                                                    ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..e612ea3
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.direct.transformed.expect
@@ -0,0 +1,39 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field self::A aField = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set aSetter(self::A value) → void {}
+  method test() → void {
+    self::A aLocal;
+    for (final dynamic #t1 in self::f<dynamic>()) {
+      aLocal = #t1;
+    }
+    for (final dynamic #t2 in self::f<dynamic>()) {
+      this.{self::C::aField} = #t2;
+    }
+    for (final dynamic #t3 in self::f<dynamic>()) {
+      this.{self::C::aSetter} = #t3;
+    }
+    for (final dynamic #t4 in self::f<dynamic>()) {
+      self::aTopLevel = #t4;
+    }
+    for (final dynamic #t5 in self::f<dynamic>()) {
+      self::aTopLevelSetter = #t5;
+    }
+  }
+}
+static field self::A aTopLevel;
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static set aTopLevelSetter(self::A value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..c5b3997
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_identifier_downwards.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field self::A aField = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set aSetter(self::A value) → void {}
+  method test() → void {
+    self::A aLocal;
+    for (final self::A #t1 in self::f<core::Iterable<self::A>>()) {
+      aLocal = #t1;
+    }
+    for (final self::A #t2 in self::f<core::Iterable<self::A>>()) {
+      this.{self::C::aField} = #t2;
+    }
+    for (final self::A #t3 in self::f<core::Iterable<self::A>>()) {
+      this.{self::C::aSetter} = #t3;
+    }
+    for (final self::A #t4 in self::f<core::Iterable<self::A>>()) {
+      self::aTopLevel = #t4;
+    }
+    for (final self::A #t5 in self::f<core::Iterable<self::A>>()) {
+      self::aTopLevelSetter = #t5;
+    }
+  }
+}
+static field self::A aTopLevel;
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static set aTopLevelSetter(self::A value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.direct.transformed.expect
new file mode 100644
index 0000000..4381b61
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.direct.transformed.expect
@@ -0,0 +1,82 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        core::String s;
+        for (core::int x in s) {
+        }
+        {
+          asy::_StreamIterator<core::int> :for-iterator = new asy::_StreamIterator::•<core::int>(s);
+          try
+            #L2:
+            while (true) {
+              [yield] let dynamic #t1 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                core::int x = :for-iterator.{asy::_StreamIterator::current};
+                {}
+              }
+              else
+                break #L2;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        core::int y;
+        for (final dynamic #t3 in s) {
+          y = #t3;
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(s);
+          try
+            #L3:
+            while (true) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t5 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  y = #t5;
+                }
+              }
+              else
+                break #L3;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
new file mode 100644
index 0000000..204c5b3
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
@@ -0,0 +1,97 @@
+library test;
+import self as self;
+import "dart:async" as asy;
+import "dart:core" as core;
+
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        core::String s;
+        for (final dynamic #t1 in let final core::String #t2 = s in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:10:46: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::Iterable<dynamic>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::Iterable<dynamic>'.
+  for (int x in /*@error=InvalidAssignment*/ s) {}
+                                             ^") {
+          core::int x = #t1 as{TypeError} core::int;
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(let final core::String #t3 = s in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:11:52: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::Stream<dynamic>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.async::Stream<dynamic>'.
+  await for (int x in /*@error=InvalidAssignment*/ s) {}
+                                                   ^");
+          try
+            #L2:
+            while (true) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t5 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  core::int x = #t5 as{TypeError} core::int;
+                }
+              }
+              else
+                break #L2;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        core::int y;
+        for (final dynamic #t7 in let final core::String #t8 = s in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:13:42: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::Iterable<dynamic>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::Iterable<dynamic>'.
+  for (y in /*@error=InvalidAssignment*/ s) {}
+                                         ^") {
+          y = #t7 as{TypeError} core::int;
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(let final core::String #t9 = s in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:14:48: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.async::Stream<dynamic>'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.async::Stream<dynamic>'.
+  await for (y in /*@error=InvalidAssignment*/ s) {}
+                                               ^");
+          try
+            #L3:
+            while (true) {
+              [yield] let dynamic #t10 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t11 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  y = #t11 as{TypeError} core::int;
+                }
+              }
+              else
+                break #L3;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t12 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..df5d861
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.direct.transformed.expect
@@ -0,0 +1,148 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        core::Iterable<self::A> iterable;
+        asy::Stream<self::A> stream;
+        self::A a;
+        self::B b;
+        core::int i;
+        for (final self::A #t1 in iterable) {
+          a = #t1;
+        }
+        {
+          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(stream);
+          try
+            #L2:
+            while (true) {
+              [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final self::A #t3 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  a = #t3;
+                }
+              }
+              else
+                break #L2;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        for (final self::A #t5 in iterable) {
+          b = #t5;
+        }
+        {
+          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(stream);
+          try
+            #L3:
+            while (true) {
+              [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final self::A #t7 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  b = #t7;
+                }
+              }
+              else
+                break #L3;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t8 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        for (final self::A #t9 in iterable) {
+          i = #t9;
+        }
+        {
+          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(stream);
+          try
+            #L4:
+            while (true) {
+              [yield] let dynamic #t10 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final self::A #t11 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  i = #t11;
+                }
+              }
+              else
+                break #L4;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t12 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        for (final dynamic #t13 in self::f<dynamic>()) {
+          a = #t13;
+        }
+        {
+          asy::_StreamIterator<dynamic> :for-iterator = new asy::_StreamIterator::•<dynamic>(self::f<dynamic>());
+          try
+            #L5:
+            while (true) {
+              [yield] let dynamic #t14 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final dynamic #t15 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  a = #t15;
+                }
+              }
+              else
+                break #L5;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t16 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..b5801f0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
@@ -0,0 +1,154 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → dynamic /* originally async */ {
+  final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
+  asy::FutureOr<dynamic> :return_value;
+  dynamic :async_stack_trace;
+  dynamic :async_op_then;
+  dynamic :async_op_error;
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  dynamic :saved_try_context_var0;
+  dynamic :saved_try_context_var1;
+  dynamic :exception0;
+  dynamic :stack_trace0;
+  function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
+    try {
+      #L1:
+      {
+        core::Iterable<self::A> iterable;
+        asy::Stream<self::A> stream;
+        self::A a;
+        self::B b;
+        core::int i;
+        for (final self::A #t1 in iterable) {
+          a = #t1;
+        }
+        {
+          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(stream);
+          try
+            #L2:
+            while (true) {
+              [yield] let dynamic #t2 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final self::A #t3 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  a = #t3;
+                }
+              }
+              else
+                break #L2;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t4 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        for (final self::A #t5 in iterable) {
+          b = #t5 as{TypeError} self::B;
+        }
+        {
+          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(stream);
+          try
+            #L3:
+            while (true) {
+              [yield] let dynamic #t6 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final self::A #t7 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  b = #t7 as{TypeError} self::B;
+                }
+              }
+              else
+                break #L3;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t8 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        for (final self::A #t9 in iterable) {
+          i = let final self::A #t10 = #t9 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart:26:39: Error: A value of type 'test::A' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  for (i /*@error=InvalidAssignment*/ in iterable) {}
+                                      ^";
+        }
+        {
+          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(stream);
+          try
+            #L4:
+            while (true) {
+              [yield] let dynamic #t11 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final self::A #t12 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  i = let final self::A #t13 = #t12 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart:27:45: Error: A value of type 'test::A' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  await for (i /*@error=InvalidAssignment*/ in stream) {}
+                                            ^";
+                }
+              }
+              else
+                break #L4;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t14 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+        for (final self::A #t15 in self::f<core::Iterable<self::A>>()) {
+          a = #t15;
+        }
+        {
+          asy::_StreamIterator<self::A> :for-iterator = new asy::_StreamIterator::•<self::A>(self::f<asy::Stream<self::A>>());
+          try
+            #L5:
+            while (true) {
+              [yield] let dynamic #t16 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              if(:result) {
+                final self::A #t17 = :for-iterator.{asy::_StreamIterator::current};
+                {
+                  a = #t17;
+                }
+              }
+              else
+                break #L5;
+            }
+          finally
+            if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
+              [yield] let dynamic #t18 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              :result;
+            }
+        }
+      }
+      :completer.{asy::Completer::complete}(:return_value);
+      return;
+    }
+    on dynamic catch(dynamic :exception, dynamic :stack_trace) {
+      :completer.{asy::Completer::completeError}(:exception, :stack_trace);
+    }
+  :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
+  :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+  :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+  asy::Future::microtask<dynamic>(:async_op);
+  return :completer.{asy::Completer::future};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.direct.transformed.expect
new file mode 100644
index 0000000..53d59d1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.direct.transformed.expect
@@ -0,0 +1,65 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::C
+    return null;
+  operator *(self::D value) → self::C
+    return null;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::E
+    return null;
+  operator *(self::F value) → self::E
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class G extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int i) → self::A
+    return null;
+  operator []=(core::int i, self::B value) → void {}
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test1(self::G g) → void {
+  let final dynamic #t1 = g in let final dynamic #t2 = 0 in #t1.[]=(#t2, #t1.[](#t2).*(self::f<dynamic>()));
+  dynamic x = let final dynamic #t3 = g in let final dynamic #t4 = 0 in let final dynamic #t5 = #t3.[](#t4).*(self::f<dynamic>()) in let final dynamic #t6 = #t3.[]=(#t4, #t5) in #t5;
+}
+static method test2(self::G g) → void {
+  let final dynamic #t7 = g in let final dynamic #t8 = 0 in let final dynamic #t9 = #t7.[](#t8).+(1) in let final dynamic #t10 = #t7.[]=(#t8, #t9) in #t9;
+  dynamic x = let final dynamic #t11 = g in let final dynamic #t12 = 0 in let final dynamic #t13 = #t11.[](#t12).+(1) in let final dynamic #t14 = #t11.[]=(#t12, #t13) in #t13;
+}
+static method test3(self::G g) → void {
+  let final dynamic #t15 = g in let final dynamic #t16 = 0 in #t15.[]=(#t16, #t15.[](#t16).+(1));
+  dynamic x = let final dynamic #t17 = g in let final dynamic #t18 = 0 in let final dynamic #t19 = #t17.[](#t18) in let final dynamic #t20 = #t17.[]=(#t18, #t19.+(1)) in #t19;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.transformed.expect
new file mode 100644
index 0000000..9a5b546
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/indexed_assign_combiner.dart.strong.transformed.expect
@@ -0,0 +1,65 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::C
+    return null;
+  operator *(self::D value) → self::C
+    return null;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::E
+    return null;
+  operator *(self::F value) → self::E
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class G extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int i) → self::A
+    return null;
+  operator []=(core::int i, self::B value) → void {}
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test1(self::G g) → void {
+  let final self::G #t1 = g in let final core::int #t2 = 0 in #t1.{self::G::[]=}(#t2, #t1.{self::G::[]}(#t2).{self::A::*}(self::f<dynamic>() as{TypeError} self::D));
+  self::C x = let final self::G #t3 = g in let final core::int #t4 = 0 in let final self::C #t5 = #t3.{self::G::[]}(#t4).{self::A::*}(self::f<dynamic>() as{TypeError} self::D) in let final void #t6 = #t3.{self::G::[]=}(#t4, #t5) in #t5;
+}
+static method test2(self::G g) → void {
+  let final self::G #t7 = g in let final core::int #t8 = 0 in let final self::C #t9 = #t7.{self::G::[]}(#t8).{self::A::+}(1) in let final void #t10 = #t7.{self::G::[]=}(#t8, #t9) in #t9;
+  self::C x = let final self::G #t11 = g in let final core::int #t12 = 0 in let final self::C #t13 = #t11.{self::G::[]}(#t12).{self::A::+}(1) in let final void #t14 = #t11.{self::G::[]=}(#t12, #t13) in #t13;
+}
+static method test3(self::G g) → void {
+  let final self::G #t15 = g in let final core::int #t16 = 0 in #t15.{self::G::[]=}(#t16, #t15.{self::G::[]}(#t16).{self::A::+}(1));
+  self::A x = let final self::G #t17 = g in let final core::int #t18 = 0 in let final self::A #t19 = #t17.{self::G::[]}(#t18) in let final void #t20 = #t17.{self::G::[]=}(#t18, #t19.{self::A::+}(1)) in #t19;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.direct.transformed.expect
new file mode 100644
index 0000000..233af9d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.direct.transformed.expect
@@ -0,0 +1,52 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    this.{self::Test::member} = self::f<dynamic>();
+    this.{self::Test::member}.==(null) ? this.{self::Test::member} = self::f<dynamic>() : null;
+    this.{self::Test::member} = this.{self::Test::member}.+(self::f<dynamic>());
+    this.{self::Test::member} = this.{self::Test::member}.*(self::f<dynamic>());
+    this.{self::Test::member} = this.{self::Test::member}.&(self::f<dynamic>());
+    this.{self::Test::member} = this.{self::Test::member}.-(1);
+    this.{self::Test::member} = this.{self::Test::member}.-(1);
+    dynamic v1 = this.{self::Test::member} = self::f<dynamic>();
+    dynamic v2 = let final dynamic #t1 = this.{self::Test::member} in #t1.==(null) ? this.{self::Test::member} = self::f<dynamic>() : #t1;
+    dynamic v3 = this.{self::Test::member} = this.{self::Test::member}.+(self::f<dynamic>());
+    dynamic v4 = this.{self::Test::member} = this.{self::Test::member}.*(self::f<dynamic>());
+    dynamic v5 = this.{self::Test::member} = this.{self::Test::member}.&(self::f<dynamic>());
+    dynamic v6 = this.{self::Test::member} = this.{self::Test::member}.-(1);
+    dynamic v7 = let final dynamic #t2 = this.{self::Test::member} in let final dynamic #t3 = this.{self::Test::member} = #t2.-(1) in #t2;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.transformed.expect
new file mode 100644
index 0000000..128a53e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this.dart.strong.transformed.expect
@@ -0,0 +1,52 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    this.{self::Test::member} = self::f<self::B>();
+    this.{self::Test::member}.{core::Object::==}(null) ?{self::B} this.{self::Test::member} = self::f<self::B>() : null;
+    this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
+    this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
+    self::B v1 = this.{self::Test::member} = self::f<self::B>();
+    self::B v2 = let final self::B #t1 = this.{self::Test::member} in #t1.{core::Object::==}(null) ?{self::B} this.{self::Test::member} = self::f<self::B>() : #t1;
+    self::A v3 = this.{self::Test::member} = this.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    self::B v4 = this.{self::Test::member} = this.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    self::C v5 = this.{self::Test::member} = this.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    self::B v6 = this.{self::Test::member} = this.{self::Test::member}.{self::B::-}(1);
+    self::B v7 = let final self::B #t2 = this.{self::Test::member} in let final self::B #t3 = this.{self::Test::member} = #t2.{self::B::-}(1) in #t2;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..0a5df04
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.direct.transformed.expect
@@ -0,0 +1,63 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    dynamic v1 = this.{self::Test1::t} = self::getInt();
+    dynamic v2 = this.{self::Test1::t} = self::getNum();
+    dynamic v4 = let final dynamic #t1 = this.{self::Test1::t} in #t1.==(null) ? this.{self::Test1::t} = self::getInt() : #t1;
+    dynamic v5 = let final dynamic #t2 = this.{self::Test1::t} in #t2.==(null) ? this.{self::Test1::t} = self::getNum() : #t2;
+    dynamic v7 = this.{self::Test1::t} = this.{self::Test1::t}.+(self::getInt());
+    dynamic v8 = this.{self::Test1::t} = this.{self::Test1::t}.+(self::getNum());
+    dynamic v10 = this.{self::Test1::t} = this.{self::Test1::t}.+(1);
+    dynamic v11 = let final dynamic #t3 = this.{self::Test1::t} in let final dynamic #t4 = this.{self::Test1::t} = #t3.+(1) in #t3;
+  }
+}
+class Test2 extends core::Object {
+  field core::num t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    dynamic v1 = this.{self::Test2::t} = self::getInt();
+    dynamic v2 = this.{self::Test2::t} = self::getNum();
+    dynamic v3 = this.{self::Test2::t} = self::getDouble();
+    dynamic v4 = let final dynamic #t5 = this.{self::Test2::t} in #t5.==(null) ? this.{self::Test2::t} = self::getInt() : #t5;
+    dynamic v5 = let final dynamic #t6 = this.{self::Test2::t} in #t6.==(null) ? this.{self::Test2::t} = self::getNum() : #t6;
+    dynamic v6 = let final dynamic #t7 = this.{self::Test2::t} in #t7.==(null) ? this.{self::Test2::t} = self::getDouble() : #t7;
+    dynamic v7 = this.{self::Test2::t} = this.{self::Test2::t}.+(self::getInt());
+    dynamic v8 = this.{self::Test2::t} = this.{self::Test2::t}.+(self::getNum());
+    dynamic v9 = this.{self::Test2::t} = this.{self::Test2::t}.+(self::getDouble());
+    dynamic v10 = this.{self::Test2::t} = this.{self::Test2::t}.+(1);
+    dynamic v11 = let final dynamic #t8 = this.{self::Test2::t} in let final dynamic #t9 = this.{self::Test2::t} = #t8.+(1) in #t8;
+  }
+}
+class Test3 extends core::Object {
+  field core::double t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test3() → void {
+    dynamic v2 = this.{self::Test3::t} = self::getNum();
+    dynamic v3 = this.{self::Test3::t} = self::getDouble();
+    dynamic v5 = let final dynamic #t10 = this.{self::Test3::t} in #t10.==(null) ? this.{self::Test3::t} = self::getNum() : #t10;
+    dynamic v6 = let final dynamic #t11 = this.{self::Test3::t} in #t11.==(null) ? this.{self::Test3::t} = self::getDouble() : #t11;
+    dynamic v7 = this.{self::Test3::t} = this.{self::Test3::t}.+(self::getInt());
+    dynamic v8 = this.{self::Test3::t} = this.{self::Test3::t}.+(self::getNum());
+    dynamic v9 = this.{self::Test3::t} = this.{self::Test3::t}.+(self::getDouble());
+    dynamic v10 = this.{self::Test3::t} = this.{self::Test3::t}.+(1);
+    dynamic v11 = let final dynamic #t12 = this.{self::Test3::t} in let final dynamic #t13 = this.{self::Test3::t} = #t12.+(1) in #t12;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..df44b13
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_implicit_this_upwards.dart.strong.transformed.expect
@@ -0,0 +1,63 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    core::int v1 = this.{self::Test1::t} = self::getInt();
+    core::num v2 = this.{self::Test1::t} = self::getNum() as{TypeError} core::int;
+    core::int v4 = let final core::int #t1 = this.{self::Test1::t} in #t1.{core::num::==}(null) ?{core::int} this.{self::Test1::t} = self::getInt() : #t1;
+    core::num v5 = let final core::int #t2 = this.{self::Test1::t} in #t2.{core::num::==}(null) ?{core::num} this.{self::Test1::t} = self::getNum() as{TypeError} core::int : #t2;
+    core::int v7 = this.{self::Test1::t} = this.{self::Test1::t}.{core::num::+}(self::getInt());
+    core::num v8 = this.{self::Test1::t} = this.{self::Test1::t}.{core::num::+}(self::getNum()) as{TypeError} core::int;
+    core::int v10 = this.{self::Test1::t} = this.{self::Test1::t}.{core::num::+}(1);
+    core::int v11 = let final core::int #t3 = this.{self::Test1::t} in let final core::int #t4 = this.{self::Test1::t} = #t3.{core::num::+}(1) in #t3;
+  }
+}
+class Test2 extends core::Object {
+  field core::num t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    core::int v1 = this.{self::Test2::t} = self::getInt();
+    core::num v2 = this.{self::Test2::t} = self::getNum();
+    core::double v3 = this.{self::Test2::t} = self::getDouble();
+    core::num v4 = let final core::num #t5 = this.{self::Test2::t} in #t5.{core::num::==}(null) ?{core::num} this.{self::Test2::t} = self::getInt() : #t5;
+    core::num v5 = let final core::num #t6 = this.{self::Test2::t} in #t6.{core::num::==}(null) ?{core::num} this.{self::Test2::t} = self::getNum() : #t6;
+    core::num v6 = let final core::num #t7 = this.{self::Test2::t} in #t7.{core::num::==}(null) ?{core::num} this.{self::Test2::t} = self::getDouble() : #t7;
+    core::num v7 = this.{self::Test2::t} = this.{self::Test2::t}.{core::num::+}(self::getInt());
+    core::num v8 = this.{self::Test2::t} = this.{self::Test2::t}.{core::num::+}(self::getNum());
+    core::num v9 = this.{self::Test2::t} = this.{self::Test2::t}.{core::num::+}(self::getDouble());
+    core::num v10 = this.{self::Test2::t} = this.{self::Test2::t}.{core::num::+}(1);
+    core::num v11 = let final core::num #t8 = this.{self::Test2::t} in let final core::num #t9 = this.{self::Test2::t} = #t8.{core::num::+}(1) in #t8;
+  }
+}
+class Test3 extends core::Object {
+  field core::double t = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test3() → void {
+    core::num v2 = this.{self::Test3::t} = self::getNum() as{TypeError} core::double;
+    core::double v3 = this.{self::Test3::t} = self::getDouble();
+    core::num v5 = let final core::double #t10 = this.{self::Test3::t} in #t10.{core::num::==}(null) ?{core::num} this.{self::Test3::t} = self::getNum() as{TypeError} core::double : #t10;
+    core::double v6 = let final core::double #t11 = this.{self::Test3::t} in #t11.{core::num::==}(null) ?{core::double} this.{self::Test3::t} = self::getDouble() : #t11;
+    core::double v7 = this.{self::Test3::t} = this.{self::Test3::t}.{core::double::+}(self::getInt());
+    core::double v8 = this.{self::Test3::t} = this.{self::Test3::t}.{core::double::+}(self::getNum());
+    core::double v9 = this.{self::Test3::t} = this.{self::Test3::t}.{core::double::+}(self::getDouble());
+    core::double v10 = this.{self::Test3::t} = this.{self::Test3::t}.{core::double::+}(1);
+    core::double v11 = let final core::double #t12 = this.{self::Test3::t} in let final core::double #t13 = this.{self::Test3::t} = #t12.{core::double::+}(1) in #t12;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.direct.transformed.expect
new file mode 100644
index 0000000..650665c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::double> a = <core::double>[];
+static field dynamic b = let final dynamic #t1 = self::a in let final dynamic #t2 = 0 in let final dynamic #t3 = 1.0 in let final dynamic #t4 = #t1.[]=(#t2, #t3) in #t3;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.strong.transformed.expect
new file mode 100644
index 0000000..52eb394
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::double> a = <core::double>[];
+static field core::double b = let final core::List<core::double> #t1 = self::a in let final core::int #t2 = 0 in let final core::double #t3 = 1.0 in let final void #t4 = #t1.{core::List::[]=}(#t2, #t3) in #t3;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.direct.transformed.expect
new file mode 100644
index 0000000..c460798
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.direct.transformed.expect
@@ -0,0 +1,60 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+  method test() → void {
+    self::Test t = self::f<dynamic>();
+    t.[]=(self::f<dynamic>(), self::f<dynamic>());
+    let final dynamic #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.[](#t2).==(null) ? let final dynamic #t3 = self::f<dynamic>() in let final dynamic #t4 = #t1.[]=(#t2, #t3) in #t3 : null;
+    let final dynamic #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.[]=(#t6, #t5.[](#t6).+(self::f<dynamic>()));
+    let final dynamic #t7 = t in let final dynamic #t8 = self::f<dynamic>() in #t7.[]=(#t8, #t7.[](#t8).*(self::f<dynamic>()));
+    let final dynamic #t9 = t in let final dynamic #t10 = self::f<dynamic>() in #t9.[]=(#t10, #t9.[](#t10).&(self::f<dynamic>()));
+    let final dynamic #t11 = t in let final dynamic #t12 = self::f<dynamic>() in let final dynamic #t13 = #t11.[](#t12).-(1) in let final dynamic #t14 = #t11.[]=(#t12, #t13) in #t13;
+    let final dynamic #t15 = t in let final dynamic #t16 = self::f<dynamic>() in #t15.[]=(#t16, #t15.[](#t16).-(1));
+    dynamic v1 = let final dynamic #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final dynamic #t19 = self::f<dynamic>() in let final dynamic #t20 = #t17.[]=(#t18, #t19) in #t19;
+    dynamic v2 = let final dynamic #t21 = t in let final dynamic #t22 = self::f<dynamic>() in let final dynamic #t23 = #t21.[](#t22) in #t23.==(null) ? let final dynamic #t24 = self::f<dynamic>() in let final dynamic #t25 = #t21.[]=(#t22, #t24) in #t24 : #t23;
+    dynamic v3 = let final dynamic #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final dynamic #t28 = #t26.[](#t27).+(self::f<dynamic>()) in let final dynamic #t29 = #t26.[]=(#t27, #t28) in #t28;
+    dynamic v4 = let final dynamic #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final dynamic #t32 = #t30.[](#t31).*(self::f<dynamic>()) in let final dynamic #t33 = #t30.[]=(#t31, #t32) in #t32;
+    dynamic v5 = let final dynamic #t34 = t in let final dynamic #t35 = self::f<dynamic>() in let final dynamic #t36 = #t34.[](#t35).&(self::f<dynamic>()) in let final dynamic #t37 = #t34.[]=(#t35, #t36) in #t36;
+    dynamic v6 = let final dynamic #t38 = t in let final dynamic #t39 = self::f<dynamic>() in let final dynamic #t40 = #t38.[](#t39).-(1) in let final dynamic #t41 = #t38.[]=(#t39, #t40) in #t40;
+    dynamic v7 = let final dynamic #t42 = t in let final dynamic #t43 = self::f<dynamic>() in let final dynamic #t44 = #t42.[](#t43) in let final dynamic #t45 = #t42.[]=(#t43, #t44.-(1)) in #t44;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.transformed.expect
new file mode 100644
index 0000000..211cbb9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_full.dart.strong.transformed.expect
@@ -0,0 +1,60 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+  method test() → void {
+    self::Test t = self::f<self::Test>();
+    t.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index, self::f<self::B>());
+    let final self::Test #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.{self::Test::[]}(#t2 as{TypeError} self::Index).{core::Object::==}(null) ?{self::B} let final self::B #t3 = self::f<self::B>() in let final void #t4 = #t1.{self::Test::[]=}(#t2 as{TypeError} self::Index, #t3) in #t3 : null;
+    let final self::Test #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.{self::Test::[]=}(#t6 as{TypeError} self::Index, #t5.{self::Test::[]}(#t6 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B);
+    let final self::Test #t7 = t in let final dynamic #t8 = self::f<dynamic>() in #t7.{self::Test::[]=}(#t8 as{TypeError} self::Index, #t7.{self::Test::[]}(#t8 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B));
+    let final self::Test #t9 = t in let final dynamic #t10 = self::f<dynamic>() in #t9.{self::Test::[]=}(#t10 as{TypeError} self::Index, #t9.{self::Test::[]}(#t10 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A));
+    let final self::Test #t11 = t in let final dynamic #t12 = self::f<dynamic>() in let final self::B #t13 = #t11.{self::Test::[]}(#t12 as{TypeError} self::Index).{self::B::-}(1) in let final void #t14 = #t11.{self::Test::[]=}(#t12 as{TypeError} self::Index, #t13) in #t13;
+    let final self::Test #t15 = t in let final dynamic #t16 = self::f<dynamic>() in #t15.{self::Test::[]=}(#t16 as{TypeError} self::Index, #t15.{self::Test::[]}(#t16 as{TypeError} self::Index).{self::B::-}(1));
+    self::B v1 = let final self::Test #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final self::B #t19 = self::f<self::B>() in let final void #t20 = #t17.{self::Test::[]=}(#t18 as{TypeError} self::Index, #t19) in #t19;
+    self::B v2 = let final self::Test #t21 = t in let final dynamic #t22 = self::f<dynamic>() in let final self::B #t23 = #t21.{self::Test::[]}(#t22 as{TypeError} self::Index) in #t23.{core::Object::==}(null) ?{self::B} let final self::B #t24 = self::f<self::B>() in let final void #t25 = #t21.{self::Test::[]=}(#t22 as{TypeError} self::Index, #t24) in #t24 : #t23;
+    self::A v3 = let final self::Test #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final self::A #t28 = #t26.{self::Test::[]}(#t27 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B in let final void #t29 = #t26.{self::Test::[]=}(#t27 as{TypeError} self::Index, #t28) in #t28;
+    self::B v4 = let final self::Test #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final self::B #t32 = #t30.{self::Test::[]}(#t31 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B) in let final void #t33 = #t30.{self::Test::[]=}(#t31 as{TypeError} self::Index, #t32) in #t32;
+    self::C v5 = let final self::Test #t34 = t in let final dynamic #t35 = self::f<dynamic>() in let final self::C #t36 = #t34.{self::Test::[]}(#t35 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A) in let final void #t37 = #t34.{self::Test::[]=}(#t35 as{TypeError} self::Index, #t36) in #t36;
+    self::B v6 = let final self::Test #t38 = t in let final dynamic #t39 = self::f<dynamic>() in let final self::B #t40 = #t38.{self::Test::[]}(#t39 as{TypeError} self::Index).{self::B::-}(1) in let final void #t41 = #t38.{self::Test::[]=}(#t39 as{TypeError} self::Index, #t40) in #t40;
+    self::B v7 = let final self::Test #t42 = t in let final dynamic #t43 = self::f<dynamic>() in let final self::B #t44 = #t42.{self::Test::[]}(#t43 as{TypeError} self::Index) in let final void #t45 = #t42.{self::Test::[]=}(#t43 as{TypeError} self::Index, #t44.{self::B::-}(1)) in #t44;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.direct.transformed.expect
new file mode 100644
index 0000000..515c5dd
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.direct.transformed.expect
@@ -0,0 +1,71 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(self::F v) → self::C
+    return null;
+  operator -(core::int i) → self::C
+    return null;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::E v) → self::D
+    return null;
+  operator -(core::int i) → self::D
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+class E extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class F extends self::E {
+  synthetic constructor •() → void
+    : super self::E::•()
+    ;
+}
+class Test extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::A v) → void {}
+  method test() → void {
+    self::Test t = self::f<dynamic>();
+    t.[]=(self::f<dynamic>(), self::f<dynamic>());
+    let final dynamic #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.[](#t2).==(null) ? let final dynamic #t3 = self::f<dynamic>() in let final dynamic #t4 = #t1.[]=(#t2, #t3) in #t3 : null;
+    let final dynamic #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.[]=(#t6, #t5.[](#t6).+(self::f<dynamic>()));
+    let final dynamic #t7 = t in let final dynamic #t8 = self::f<dynamic>() in let final dynamic #t9 = #t7.[](#t8).-(1) in let final dynamic #t10 = #t7.[]=(#t8, #t9) in #t9;
+    let final dynamic #t11 = t in let final dynamic #t12 = self::f<dynamic>() in #t11.[]=(#t12, #t11.[](#t12).-(1));
+    dynamic v1 = let final dynamic #t13 = t in let final dynamic #t14 = self::f<dynamic>() in let final dynamic #t15 = self::f<dynamic>() in let final dynamic #t16 = #t13.[]=(#t14, #t15) in #t15;
+    dynamic v2 = let final dynamic #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final dynamic #t19 = #t17.[](#t18) in #t19.==(null) ? let final dynamic #t20 = self::f<dynamic>() in let final dynamic #t21 = #t17.[]=(#t18, #t20) in #t20 : #t19;
+    dynamic v3 = let final dynamic #t22 = t in let final dynamic #t23 = self::f<dynamic>() in let final dynamic #t24 = #t22.[](#t23).+(self::f<dynamic>()) in let final dynamic #t25 = #t22.[]=(#t23, #t24) in #t24;
+    dynamic v4 = let final dynamic #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final dynamic #t28 = #t26.[](#t27).-(1) in let final dynamic #t29 = #t26.[]=(#t27, #t28) in #t28;
+    dynamic v5 = let final dynamic #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final dynamic #t32 = #t30.[](#t31) in let final dynamic #t33 = #t30.[]=(#t31, #t32.-(1)) in #t32;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.transformed.expect
new file mode 100644
index 0000000..8c2dd0c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_set_vs_get.dart.strong.transformed.expect
@@ -0,0 +1,71 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(self::F v) → self::C
+    return null;
+  operator -(core::int i) → self::C
+    return null;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::E v) → self::D
+    return null;
+  operator -(core::int i) → self::D
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+class E extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class F extends self::E {
+  synthetic constructor •() → void
+    : super self::E::•()
+    ;
+}
+class Test extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::A v) → void {}
+  method test() → void {
+    self::Test t = self::f<self::Test>();
+    t.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index, self::f<self::A>());
+    let final self::Test #t1 = t in let final dynamic #t2 = self::f<dynamic>() in #t1.{self::Test::[]}(#t2 as{TypeError} self::Index).{core::Object::==}(null) ?{self::A} let final self::A #t3 = self::f<self::A>() in let final void #t4 = #t1.{self::Test::[]=}(#t2 as{TypeError} self::Index, #t3) in #t3 : null;
+    let final self::Test #t5 = t in let final dynamic #t6 = self::f<dynamic>() in #t5.{self::Test::[]=}(#t6 as{TypeError} self::Index, #t5.{self::Test::[]}(#t6 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::E));
+    let final self::Test #t7 = t in let final dynamic #t8 = self::f<dynamic>() in let final self::D #t9 = #t7.{self::Test::[]}(#t8 as{TypeError} self::Index).{self::B::-}(1) in let final void #t10 = #t7.{self::Test::[]=}(#t8 as{TypeError} self::Index, #t9) in #t9;
+    let final self::Test #t11 = t in let final dynamic #t12 = self::f<dynamic>() in #t11.{self::Test::[]=}(#t12 as{TypeError} self::Index, #t11.{self::Test::[]}(#t12 as{TypeError} self::Index).{self::B::-}(1));
+    self::A v1 = let final self::Test #t13 = t in let final dynamic #t14 = self::f<dynamic>() in let final self::A #t15 = self::f<self::A>() in let final void #t16 = #t13.{self::Test::[]=}(#t14 as{TypeError} self::Index, #t15) in #t15;
+    self::A v2 = let final self::Test #t17 = t in let final dynamic #t18 = self::f<dynamic>() in let final self::B #t19 = #t17.{self::Test::[]}(#t18 as{TypeError} self::Index) in #t19.{core::Object::==}(null) ?{self::A} let final self::A #t20 = self::f<self::A>() in let final void #t21 = #t17.{self::Test::[]=}(#t18 as{TypeError} self::Index, #t20) in #t20 : #t19;
+    self::D v3 = let final self::Test #t22 = t in let final dynamic #t23 = self::f<dynamic>() in let final self::D #t24 = #t22.{self::Test::[]}(#t23 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::E) in let final void #t25 = #t22.{self::Test::[]=}(#t23 as{TypeError} self::Index, #t24) in #t24;
+    self::D v4 = let final self::Test #t26 = t in let final dynamic #t27 = self::f<dynamic>() in let final self::D #t28 = #t26.{self::Test::[]}(#t27 as{TypeError} self::Index).{self::B::-}(1) in let final void #t29 = #t26.{self::Test::[]=}(#t27 as{TypeError} self::Index, #t28) in #t28;
+    self::B v5 = let final self::Test #t30 = t in let final dynamic #t31 = self::f<dynamic>() in let final self::B #t32 = #t30.{self::Test::[]}(#t31 as{TypeError} self::Index) in let final void #t33 = #t30.{self::Test::[]=}(#t31 as{TypeError} self::Index, #t32.{self::B::-}(1)) in #t32;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.direct.transformed.expect
new file mode 100644
index 0000000..02ff3dc
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.direct.transformed.expect
@@ -0,0 +1,64 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Base extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+}
+class Test extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    super.{self::Base::[]=}(self::f<dynamic>(), self::f<dynamic>());
+    let final dynamic #t1 = self::f<dynamic>() in super.{self::Base::[]}(#t1).==(null) ? let final dynamic #t2 = self::f<dynamic>() in let final dynamic #t3 = super.{self::Base::[]=}(#t1, #t2) in #t2 : null;
+    let final dynamic #t4 = self::f<dynamic>() in super.{self::Base::[]=}(#t4, super.{self::Base::[]}(#t4).+(self::f<dynamic>()));
+    let final dynamic #t5 = self::f<dynamic>() in super.{self::Base::[]=}(#t5, super.{self::Base::[]}(#t5).*(self::f<dynamic>()));
+    let final dynamic #t6 = self::f<dynamic>() in super.{self::Base::[]=}(#t6, super.{self::Base::[]}(#t6).&(self::f<dynamic>()));
+    let final dynamic #t7 = self::f<dynamic>() in let final dynamic #t8 = super.{self::Base::[]}(#t7).-(1) in let final dynamic #t9 = super.{self::Base::[]=}(#t7, #t8) in #t8;
+    let final dynamic #t10 = self::f<dynamic>() in super.{self::Base::[]=}(#t10, super.{self::Base::[]}(#t10).-(1));
+    dynamic v1 = let final dynamic #t11 = self::f<dynamic>() in let final dynamic #t12 = self::f<dynamic>() in let final dynamic #t13 = super.{self::Base::[]=}(#t11, #t12) in #t12;
+    dynamic v2 = let final dynamic #t14 = self::f<dynamic>() in let final dynamic #t15 = super.{self::Base::[]}(#t14) in #t15.==(null) ? let final dynamic #t16 = self::f<dynamic>() in let final dynamic #t17 = super.{self::Base::[]=}(#t14, #t16) in #t16 : #t15;
+    dynamic v3 = let final dynamic #t18 = self::f<dynamic>() in let final dynamic #t19 = super.{self::Base::[]}(#t18).+(self::f<dynamic>()) in let final dynamic #t20 = super.{self::Base::[]=}(#t18, #t19) in #t19;
+    dynamic v4 = let final dynamic #t21 = self::f<dynamic>() in let final dynamic #t22 = super.{self::Base::[]}(#t21).*(self::f<dynamic>()) in let final dynamic #t23 = super.{self::Base::[]=}(#t21, #t22) in #t22;
+    dynamic v5 = let final dynamic #t24 = self::f<dynamic>() in let final dynamic #t25 = super.{self::Base::[]}(#t24).&(self::f<dynamic>()) in let final dynamic #t26 = super.{self::Base::[]=}(#t24, #t25) in #t25;
+    dynamic v6 = let final dynamic #t27 = self::f<dynamic>() in let final dynamic #t28 = super.{self::Base::[]}(#t27).-(1) in let final dynamic #t29 = super.{self::Base::[]=}(#t27, #t28) in #t28;
+    dynamic v7 = let final dynamic #t30 = self::f<dynamic>() in let final dynamic #t31 = super.{self::Base::[]}(#t30) in let final dynamic #t32 = super.{self::Base::[]=}(#t30, #t31.-(1)) in #t31;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.transformed.expect
new file mode 100644
index 0000000..ac4968c
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super.dart.strong.transformed.expect
@@ -0,0 +1,64 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Base extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+}
+class Test extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    super.{self::Base::[]=}(self::f<dynamic>() as{TypeError} self::Index, self::f<self::B>());
+    let final dynamic #t1 = self::f<dynamic>() in super.{self::Base::[]}(#t1 as{TypeError} self::Index).{core::Object::==}(null) ?{self::B} let final self::B #t2 = self::f<self::B>() in let final void #t3 = super.{self::Base::[]=}(#t1 as{TypeError} self::Index, #t2) in #t2 : null;
+    let final dynamic #t4 = self::f<dynamic>() in super.{self::Base::[]=}(#t4 as{TypeError} self::Index, super.{self::Base::[]}(#t4 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B);
+    let final dynamic #t5 = self::f<dynamic>() in super.{self::Base::[]=}(#t5 as{TypeError} self::Index, super.{self::Base::[]}(#t5 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B));
+    let final dynamic #t6 = self::f<dynamic>() in super.{self::Base::[]=}(#t6 as{TypeError} self::Index, super.{self::Base::[]}(#t6 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A));
+    let final dynamic #t7 = self::f<dynamic>() in let final self::B #t8 = super.{self::Base::[]}(#t7 as{TypeError} self::Index).{self::B::-}(1) in let final void #t9 = super.{self::Base::[]=}(#t7 as{TypeError} self::Index, #t8) in #t8;
+    let final dynamic #t10 = self::f<dynamic>() in super.{self::Base::[]=}(#t10 as{TypeError} self::Index, super.{self::Base::[]}(#t10 as{TypeError} self::Index).{self::B::-}(1));
+    self::B v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B #t12 = self::f<self::B>() in let final void #t13 = super.{self::Base::[]=}(#t11 as{TypeError} self::Index, #t12) in #t12;
+    self::B v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B #t15 = super.{self::Base::[]}(#t14 as{TypeError} self::Index) in #t15.{core::Object::==}(null) ?{self::B} let final self::B #t16 = self::f<self::B>() in let final void #t17 = super.{self::Base::[]=}(#t14 as{TypeError} self::Index, #t16) in #t16 : #t15;
+    self::A v3 = let final dynamic #t18 = self::f<dynamic>() in let final self::A #t19 = super.{self::Base::[]}(#t18 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B in let final void #t20 = super.{self::Base::[]=}(#t18 as{TypeError} self::Index, #t19) in #t19;
+    self::B v4 = let final dynamic #t21 = self::f<dynamic>() in let final self::B #t22 = super.{self::Base::[]}(#t21 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B) in let final void #t23 = super.{self::Base::[]=}(#t21 as{TypeError} self::Index, #t22) in #t22;
+    self::C v5 = let final dynamic #t24 = self::f<dynamic>() in let final self::C #t25 = super.{self::Base::[]}(#t24 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A) in let final void #t26 = super.{self::Base::[]=}(#t24 as{TypeError} self::Index, #t25) in #t25;
+    self::B v6 = let final dynamic #t27 = self::f<dynamic>() in let final self::B #t28 = super.{self::Base::[]}(#t27 as{TypeError} self::Index).{self::B::-}(1) in let final void #t29 = super.{self::Base::[]=}(#t27 as{TypeError} self::Index, #t28) in #t28;
+    self::B v7 = let final dynamic #t30 = self::f<dynamic>() in let final self::B #t31 = super.{self::Base::[]}(#t30 as{TypeError} self::Index) in let final void #t32 = super.{self::Base::[]=}(#t30 as{TypeError} self::Index, #t31.{self::B::-}(1)) in #t31;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..7ad93e72
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_super_upwards.dart.direct.transformed.expect
@@ -0,0 +1,169 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class Base<T extends core::Object, U extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::String s) → self::Base::T
+    return this.{self::Base::getValue}(s);
+  operator []=(core::String s, self::Base::U v) → void
+    return this.{self::Base::setValue}(s, v);
+  abstract method getValue(core::String s) → self::Base::T;
+  abstract method setValue(core::String s, self::Base::U v) → void;
+}
+abstract class Test1 extends self::Base<core::int, core::int> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v1 = let final dynamic #t1 = "x" in let final dynamic #t2 = self::getInt() in let final dynamic #t3 = super.{self::Base::[]=}(#t1, #t2) in #t2;
+    dynamic v2 = let final dynamic #t4 = "x" in let final dynamic #t5 = self::getNum() in let final dynamic #t6 = super.{self::Base::[]=}(#t4, #t5) in #t5;
+    dynamic v4 = let final dynamic #t7 = "x" in let final dynamic #t8 = super.{self::Base::[]}(#t7) in #t8.==(null) ? let final dynamic #t9 = self::getInt() in let final dynamic #t10 = super.{self::Base::[]=}(#t7, #t9) in #t9 : #t8;
+    dynamic v5 = let final dynamic #t11 = "x" in let final dynamic #t12 = super.{self::Base::[]}(#t11) in #t12.==(null) ? let final dynamic #t13 = self::getNum() in let final dynamic #t14 = super.{self::Base::[]=}(#t11, #t13) in #t13 : #t12;
+    dynamic v7 = let final dynamic #t15 = "x" in let final dynamic #t16 = super.{self::Base::[]}(#t15).+(self::getInt()) in let final dynamic #t17 = super.{self::Base::[]=}(#t15, #t16) in #t16;
+    dynamic v8 = let final dynamic #t18 = "x" in let final dynamic #t19 = super.{self::Base::[]}(#t18).+(self::getNum()) in let final dynamic #t20 = super.{self::Base::[]=}(#t18, #t19) in #t19;
+    dynamic v10 = let final dynamic #t21 = "x" in let final dynamic #t22 = super.{self::Base::[]}(#t21).+(1) in let final dynamic #t23 = super.{self::Base::[]=}(#t21, #t22) in #t22;
+    dynamic v11 = let final dynamic #t24 = "x" in let final dynamic #t25 = super.{self::Base::[]}(#t24) in let final dynamic #t26 = super.{self::Base::[]=}(#t24, #t25.+(1)) in #t25;
+  }
+}
+abstract class Test2 extends self::Base<core::int, core::num> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v1 = let final dynamic #t27 = "x" in let final dynamic #t28 = self::getInt() in let final dynamic #t29 = super.{self::Base::[]=}(#t27, #t28) in #t28;
+    dynamic v2 = let final dynamic #t30 = "x" in let final dynamic #t31 = self::getNum() in let final dynamic #t32 = super.{self::Base::[]=}(#t30, #t31) in #t31;
+    dynamic v3 = let final dynamic #t33 = "x" in let final dynamic #t34 = self::getDouble() in let final dynamic #t35 = super.{self::Base::[]=}(#t33, #t34) in #t34;
+    dynamic v4 = let final dynamic #t36 = "x" in let final dynamic #t37 = super.{self::Base::[]}(#t36) in #t37.==(null) ? let final dynamic #t38 = self::getInt() in let final dynamic #t39 = super.{self::Base::[]=}(#t36, #t38) in #t38 : #t37;
+    dynamic v5 = let final dynamic #t40 = "x" in let final dynamic #t41 = super.{self::Base::[]}(#t40) in #t41.==(null) ? let final dynamic #t42 = self::getNum() in let final dynamic #t43 = super.{self::Base::[]=}(#t40, #t42) in #t42 : #t41;
+    dynamic v6 = let final dynamic #t44 = "x" in let final dynamic #t45 = super.{self::Base::[]}(#t44) in #t45.==(null) ? let final dynamic #t46 = self::getDouble() in let final dynamic #t47 = super.{self::Base::[]=}(#t44, #t46) in #t46 : #t45;
+    dynamic v7 = let final dynamic #t48 = "x" in let final dynamic #t49 = super.{self::Base::[]}(#t48).+(self::getInt()) in let final dynamic #t50 = super.{self::Base::[]=}(#t48, #t49) in #t49;
+    dynamic v8 = let final dynamic #t51 = "x" in let final dynamic #t52 = super.{self::Base::[]}(#t51).+(self::getNum()) in let final dynamic #t53 = super.{self::Base::[]=}(#t51, #t52) in #t52;
+    dynamic v9 = let final dynamic #t54 = "x" in let final dynamic #t55 = super.{self::Base::[]}(#t54).+(self::getDouble()) in let final dynamic #t56 = super.{self::Base::[]=}(#t54, #t55) in #t55;
+    dynamic v10 = let final dynamic #t57 = "x" in let final dynamic #t58 = super.{self::Base::[]}(#t57).+(1) in let final dynamic #t59 = super.{self::Base::[]=}(#t57, #t58) in #t58;
+    dynamic v11 = let final dynamic #t60 = "x" in let final dynamic #t61 = super.{self::Base::[]}(#t60) in let final dynamic #t62 = super.{self::Base::[]=}(#t60, #t61.+(1)) in #t61;
+  }
+}
+abstract class Test3 extends self::Base<core::int, core::double> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v2 = let final dynamic #t63 = "x" in let final dynamic #t64 = self::getNum() in let final dynamic #t65 = super.{self::Base::[]=}(#t63, #t64) in #t64;
+    dynamic v3 = let final dynamic #t66 = "x" in let final dynamic #t67 = self::getDouble() in let final dynamic #t68 = super.{self::Base::[]=}(#t66, #t67) in #t67;
+    dynamic v5 = let final dynamic #t69 = "x" in let final dynamic #t70 = super.{self::Base::[]}(#t69) in #t70.==(null) ? let final dynamic #t71 = self::getNum() in let final dynamic #t72 = super.{self::Base::[]=}(#t69, #t71) in #t71 : #t70;
+    dynamic v6 = let final dynamic #t73 = "x" in let final dynamic #t74 = super.{self::Base::[]}(#t73) in #t74.==(null) ? let final dynamic #t75 = self::getDouble() in let final dynamic #t76 = super.{self::Base::[]=}(#t73, #t75) in #t75 : #t74;
+    dynamic v7 = let final dynamic #t77 = "x" in let final dynamic #t78 = super.{self::Base::[]}(#t77).+(self::getInt()) in let final dynamic #t79 = super.{self::Base::[]=}(#t77, #t78) in #t78;
+    dynamic v8 = let final dynamic #t80 = "x" in let final dynamic #t81 = super.{self::Base::[]}(#t80).+(self::getNum()) in let final dynamic #t82 = super.{self::Base::[]=}(#t80, #t81) in #t81;
+    dynamic v9 = let final dynamic #t83 = "x" in let final dynamic #t84 = super.{self::Base::[]}(#t83).+(self::getDouble()) in let final dynamic #t85 = super.{self::Base::[]=}(#t83, #t84) in #t84;
+    dynamic v10 = let final dynamic #t86 = "x" in let final dynamic #t87 = super.{self::Base::[]}(#t86).+(1) in let final dynamic #t88 = super.{self::Base::[]=}(#t86, #t87) in #t87;
+    dynamic v11 = let final dynamic #t89 = "x" in let final dynamic #t90 = super.{self::Base::[]}(#t89) in let final dynamic #t91 = super.{self::Base::[]=}(#t89, #t90.+(1)) in #t90;
+  }
+}
+abstract class Test4 extends self::Base<core::num, core::int> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v1 = let final dynamic #t92 = "x" in let final dynamic #t93 = self::getInt() in let final dynamic #t94 = super.{self::Base::[]=}(#t92, #t93) in #t93;
+    dynamic v2 = let final dynamic #t95 = "x" in let final dynamic #t96 = self::getNum() in let final dynamic #t97 = super.{self::Base::[]=}(#t95, #t96) in #t96;
+    dynamic v4 = let final dynamic #t98 = "x" in let final dynamic #t99 = super.{self::Base::[]}(#t98) in #t99.==(null) ? let final dynamic #t100 = self::getInt() in let final dynamic #t101 = super.{self::Base::[]=}(#t98, #t100) in #t100 : #t99;
+    dynamic v5 = let final dynamic #t102 = "x" in let final dynamic #t103 = super.{self::Base::[]}(#t102) in #t103.==(null) ? let final dynamic #t104 = self::getNum() in let final dynamic #t105 = super.{self::Base::[]=}(#t102, #t104) in #t104 : #t103;
+    dynamic v7 = let final dynamic #t106 = "x" in let final dynamic #t107 = super.{self::Base::[]}(#t106).+(self::getInt()) in let final dynamic #t108 = super.{self::Base::[]=}(#t106, #t107) in #t107;
+    dynamic v8 = let final dynamic #t109 = "x" in let final dynamic #t110 = super.{self::Base::[]}(#t109).+(self::getNum()) in let final dynamic #t111 = super.{self::Base::[]=}(#t109, #t110) in #t110;
+    dynamic v10 = let final dynamic #t112 = "x" in let final dynamic #t113 = super.{self::Base::[]}(#t112).+(1) in let final dynamic #t114 = super.{self::Base::[]=}(#t112, #t113) in #t113;
+    dynamic v11 = let final dynamic #t115 = "x" in let final dynamic #t116 = super.{self::Base::[]}(#t115) in let final dynamic #t117 = super.{self::Base::[]=}(#t115, #t116.+(1)) in #t116;
+  }
+}
+abstract class Test5 extends self::Base<core::num, core::num> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v1 = let final dynamic #t118 = "x" in let final dynamic #t119 = self::getInt() in let final dynamic #t120 = super.{self::Base::[]=}(#t118, #t119) in #t119;
+    dynamic v2 = let final dynamic #t121 = "x" in let final dynamic #t122 = self::getNum() in let final dynamic #t123 = super.{self::Base::[]=}(#t121, #t122) in #t122;
+    dynamic v3 = let final dynamic #t124 = "x" in let final dynamic #t125 = self::getDouble() in let final dynamic #t126 = super.{self::Base::[]=}(#t124, #t125) in #t125;
+    dynamic v4 = let final dynamic #t127 = "x" in let final dynamic #t128 = super.{self::Base::[]}(#t127) in #t128.==(null) ? let final dynamic #t129 = self::getInt() in let final dynamic #t130 = super.{self::Base::[]=}(#t127, #t129) in #t129 : #t128;
+    dynamic v5 = let final dynamic #t131 = "x" in let final dynamic #t132 = super.{self::Base::[]}(#t131) in #t132.==(null) ? let final dynamic #t133 = self::getNum() in let final dynamic #t134 = super.{self::Base::[]=}(#t131, #t133) in #t133 : #t132;
+    dynamic v6 = let final dynamic #t135 = "x" in let final dynamic #t136 = super.{self::Base::[]}(#t135) in #t136.==(null) ? let final dynamic #t137 = self::getDouble() in let final dynamic #t138 = super.{self::Base::[]=}(#t135, #t137) in #t137 : #t136;
+    dynamic v7 = let final dynamic #t139 = "x" in let final dynamic #t140 = super.{self::Base::[]}(#t139).+(self::getInt()) in let final dynamic #t141 = super.{self::Base::[]=}(#t139, #t140) in #t140;
+    dynamic v8 = let final dynamic #t142 = "x" in let final dynamic #t143 = super.{self::Base::[]}(#t142).+(self::getNum()) in let final dynamic #t144 = super.{self::Base::[]=}(#t142, #t143) in #t143;
+    dynamic v9 = let final dynamic #t145 = "x" in let final dynamic #t146 = super.{self::Base::[]}(#t145).+(self::getDouble()) in let final dynamic #t147 = super.{self::Base::[]=}(#t145, #t146) in #t146;
+    dynamic v10 = let final dynamic #t148 = "x" in let final dynamic #t149 = super.{self::Base::[]}(#t148).+(1) in let final dynamic #t150 = super.{self::Base::[]=}(#t148, #t149) in #t149;
+    dynamic v11 = let final dynamic #t151 = "x" in let final dynamic #t152 = super.{self::Base::[]}(#t151) in let final dynamic #t153 = super.{self::Base::[]=}(#t151, #t152.+(1)) in #t152;
+  }
+}
+abstract class Test6 extends self::Base<core::num, core::double> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v2 = let final dynamic #t154 = "x" in let final dynamic #t155 = self::getNum() in let final dynamic #t156 = super.{self::Base::[]=}(#t154, #t155) in #t155;
+    dynamic v3 = let final dynamic #t157 = "x" in let final dynamic #t158 = self::getDouble() in let final dynamic #t159 = super.{self::Base::[]=}(#t157, #t158) in #t158;
+    dynamic v5 = let final dynamic #t160 = "x" in let final dynamic #t161 = super.{self::Base::[]}(#t160) in #t161.==(null) ? let final dynamic #t162 = self::getNum() in let final dynamic #t163 = super.{self::Base::[]=}(#t160, #t162) in #t162 : #t161;
+    dynamic v6 = let final dynamic #t164 = "x" in let final dynamic #t165 = super.{self::Base::[]}(#t164) in #t165.==(null) ? let final dynamic #t166 = self::getDouble() in let final dynamic #t167 = super.{self::Base::[]=}(#t164, #t166) in #t166 : #t165;
+    dynamic v7 = let final dynamic #t168 = "x" in let final dynamic #t169 = super.{self::Base::[]}(#t168).+(self::getInt()) in let final dynamic #t170 = super.{self::Base::[]=}(#t168, #t169) in #t169;
+    dynamic v8 = let final dynamic #t171 = "x" in let final dynamic #t172 = super.{self::Base::[]}(#t171).+(self::getNum()) in let final dynamic #t173 = super.{self::Base::[]=}(#t171, #t172) in #t172;
+    dynamic v9 = let final dynamic #t174 = "x" in let final dynamic #t175 = super.{self::Base::[]}(#t174).+(self::getDouble()) in let final dynamic #t176 = super.{self::Base::[]=}(#t174, #t175) in #t175;
+    dynamic v10 = let final dynamic #t177 = "x" in let final dynamic #t178 = super.{self::Base::[]}(#t177).+(1) in let final dynamic #t179 = super.{self::Base::[]=}(#t177, #t178) in #t178;
+    dynamic v11 = let final dynamic #t180 = "x" in let final dynamic #t181 = super.{self::Base::[]}(#t180) in let final dynamic #t182 = super.{self::Base::[]=}(#t180, #t181.+(1)) in #t181;
+  }
+}
+abstract class Test7 extends self::Base<core::double, core::int> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v1 = let final dynamic #t183 = "x" in let final dynamic #t184 = self::getInt() in let final dynamic #t185 = super.{self::Base::[]=}(#t183, #t184) in #t184;
+    dynamic v2 = let final dynamic #t186 = "x" in let final dynamic #t187 = self::getNum() in let final dynamic #t188 = super.{self::Base::[]=}(#t186, #t187) in #t187;
+    dynamic v4 = let final dynamic #t189 = "x" in let final dynamic #t190 = super.{self::Base::[]}(#t189) in #t190.==(null) ? let final dynamic #t191 = self::getInt() in let final dynamic #t192 = super.{self::Base::[]=}(#t189, #t191) in #t191 : #t190;
+    dynamic v5 = let final dynamic #t193 = "x" in let final dynamic #t194 = super.{self::Base::[]}(#t193) in #t194.==(null) ? let final dynamic #t195 = self::getNum() in let final dynamic #t196 = super.{self::Base::[]=}(#t193, #t195) in #t195 : #t194;
+    dynamic v7 = let final dynamic #t197 = "x" in let final dynamic #t198 = super.{self::Base::[]}(#t197).+(self::getInt()) in let final dynamic #t199 = super.{self::Base::[]=}(#t197, #t198) in #t198;
+    dynamic v8 = let final dynamic #t200 = "x" in let final dynamic #t201 = super.{self::Base::[]}(#t200).+(self::getNum()) in let final dynamic #t202 = super.{self::Base::[]=}(#t200, #t201) in #t201;
+    dynamic v10 = let final dynamic #t203 = "x" in let final dynamic #t204 = super.{self::Base::[]}(#t203).+(1) in let final dynamic #t205 = super.{self::Base::[]=}(#t203, #t204) in #t204;
+    dynamic v11 = let final dynamic #t206 = "x" in let final dynamic #t207 = super.{self::Base::[]}(#t206) in let final dynamic #t208 = super.{self::Base::[]=}(#t206, #t207.+(1)) in #t207;
+  }
+}
+abstract class Test8 extends self::Base<core::double, core::num> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v1 = let final dynamic #t209 = "x" in let final dynamic #t210 = self::getInt() in let final dynamic #t211 = super.{self::Base::[]=}(#t209, #t210) in #t210;
+    dynamic v2 = let final dynamic #t212 = "x" in let final dynamic #t213 = self::getNum() in let final dynamic #t214 = super.{self::Base::[]=}(#t212, #t213) in #t213;
+    dynamic v3 = let final dynamic #t215 = "x" in let final dynamic #t216 = self::getDouble() in let final dynamic #t217 = super.{self::Base::[]=}(#t215, #t216) in #t216;
+    dynamic v4 = let final dynamic #t218 = "x" in let final dynamic #t219 = super.{self::Base::[]}(#t218) in #t219.==(null) ? let final dynamic #t220 = self::getInt() in let final dynamic #t221 = super.{self::Base::[]=}(#t218, #t220) in #t220 : #t219;
+    dynamic v5 = let final dynamic #t222 = "x" in let final dynamic #t223 = super.{self::Base::[]}(#t222) in #t223.==(null) ? let final dynamic #t224 = self::getNum() in let final dynamic #t225 = super.{self::Base::[]=}(#t222, #t224) in #t224 : #t223;
+    dynamic v6 = let final dynamic #t226 = "x" in let final dynamic #t227 = super.{self::Base::[]}(#t226) in #t227.==(null) ? let final dynamic #t228 = self::getDouble() in let final dynamic #t229 = super.{self::Base::[]=}(#t226, #t228) in #t228 : #t227;
+    dynamic v7 = let final dynamic #t230 = "x" in let final dynamic #t231 = super.{self::Base::[]}(#t230).+(self::getInt()) in let final dynamic #t232 = super.{self::Base::[]=}(#t230, #t231) in #t231;
+    dynamic v8 = let final dynamic #t233 = "x" in let final dynamic #t234 = super.{self::Base::[]}(#t233).+(self::getNum()) in let final dynamic #t235 = super.{self::Base::[]=}(#t233, #t234) in #t234;
+    dynamic v9 = let final dynamic #t236 = "x" in let final dynamic #t237 = super.{self::Base::[]}(#t236).+(self::getDouble()) in let final dynamic #t238 = super.{self::Base::[]=}(#t236, #t237) in #t237;
+    dynamic v10 = let final dynamic #t239 = "x" in let final dynamic #t240 = super.{self::Base::[]}(#t239).+(1) in let final dynamic #t241 = super.{self::Base::[]=}(#t239, #t240) in #t240;
+    dynamic v11 = let final dynamic #t242 = "x" in let final dynamic #t243 = super.{self::Base::[]}(#t242) in let final dynamic #t244 = super.{self::Base::[]=}(#t242, #t243.+(1)) in #t243;
+  }
+}
+abstract class Test9 extends self::Base<core::double, core::double> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v2 = let final dynamic #t245 = "x" in let final dynamic #t246 = self::getNum() in let final dynamic #t247 = super.{self::Base::[]=}(#t245, #t246) in #t246;
+    dynamic v3 = let final dynamic #t248 = "x" in let final dynamic #t249 = self::getDouble() in let final dynamic #t250 = super.{self::Base::[]=}(#t248, #t249) in #t249;
+    dynamic v5 = let final dynamic #t251 = "x" in let final dynamic #t252 = super.{self::Base::[]}(#t251) in #t252.==(null) ? let final dynamic #t253 = self::getNum() in let final dynamic #t254 = super.{self::Base::[]=}(#t251, #t253) in #t253 : #t252;
+    dynamic v6 = let final dynamic #t255 = "x" in let final dynamic #t256 = super.{self::Base::[]}(#t255) in #t256.==(null) ? let final dynamic #t257 = self::getDouble() in let final dynamic #t258 = super.{self::Base::[]=}(#t255, #t257) in #t257 : #t256;
+    dynamic v7 = let final dynamic #t259 = "x" in let final dynamic #t260 = super.{self::Base::[]}(#t259).+(self::getInt()) in let final dynamic #t261 = super.{self::Base::[]=}(#t259, #t260) in #t260;
+    dynamic v8 = let final dynamic #t262 = "x" in let final dynamic #t263 = super.{self::Base::[]}(#t262).+(self::getNum()) in let final dynamic #t264 = super.{self::Base::[]=}(#t262, #t263) in #t263;
+    dynamic v9 = let final dynamic #t265 = "x" in let final dynamic #t266 = super.{self::Base::[]}(#t265).+(self::getDouble()) in let final dynamic #t267 = super.{self::Base::[]=}(#t265, #t266) in #t266;
+    dynamic v10 = let final dynamic #t268 = "x" in let final dynamic #t269 = super.{self::Base::[]}(#t268).+(1) in let final dynamic #t270 = super.{self::Base::[]=}(#t268, #t269) in #t269;
+    dynamic v11 = let final dynamic #t271 = "x" in let final dynamic #t272 = super.{self::Base::[]}(#t271) in let final dynamic #t273 = super.{self::Base::[]=}(#t271, #t272.+(1)) in #t272;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.direct.transformed.expect
new file mode 100644
index 0000000..2c0f5d8
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.direct.transformed.expect
@@ -0,0 +1,59 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+  method test() → void {
+    this.[]=(self::f<dynamic>(), self::f<dynamic>());
+    let final dynamic #t1 = self::f<dynamic>() in this.[](#t1).==(null) ? let final dynamic #t2 = self::f<dynamic>() in let final dynamic #t3 = this.[]=(#t1, #t2) in #t2 : null;
+    let final dynamic #t4 = self::f<dynamic>() in this.[]=(#t4, this.[](#t4).+(self::f<dynamic>()));
+    let final dynamic #t5 = self::f<dynamic>() in this.[]=(#t5, this.[](#t5).*(self::f<dynamic>()));
+    let final dynamic #t6 = self::f<dynamic>() in this.[]=(#t6, this.[](#t6).&(self::f<dynamic>()));
+    let final dynamic #t7 = self::f<dynamic>() in let final dynamic #t8 = this.[](#t7).-(1) in let final dynamic #t9 = this.[]=(#t7, #t8) in #t8;
+    let final dynamic #t10 = self::f<dynamic>() in this.[]=(#t10, this.[](#t10).-(1));
+    dynamic v1 = let final dynamic #t11 = self::f<dynamic>() in let final dynamic #t12 = self::f<dynamic>() in let final dynamic #t13 = this.[]=(#t11, #t12) in #t12;
+    dynamic v2 = let final dynamic #t14 = self::f<dynamic>() in let final dynamic #t15 = this.[](#t14) in #t15.==(null) ? let final dynamic #t16 = self::f<dynamic>() in let final dynamic #t17 = this.[]=(#t14, #t16) in #t16 : #t15;
+    dynamic v3 = let final dynamic #t18 = self::f<dynamic>() in let final dynamic #t19 = this.[](#t18).+(self::f<dynamic>()) in let final dynamic #t20 = this.[]=(#t18, #t19) in #t19;
+    dynamic v4 = let final dynamic #t21 = self::f<dynamic>() in let final dynamic #t22 = this.[](#t21).*(self::f<dynamic>()) in let final dynamic #t23 = this.[]=(#t21, #t22) in #t22;
+    dynamic v5 = let final dynamic #t24 = self::f<dynamic>() in let final dynamic #t25 = this.[](#t24).&(self::f<dynamic>()) in let final dynamic #t26 = this.[]=(#t24, #t25) in #t25;
+    dynamic v6 = let final dynamic #t27 = self::f<dynamic>() in let final dynamic #t28 = this.[](#t27).-(1) in let final dynamic #t29 = this.[]=(#t27, #t28) in #t28;
+    dynamic v7 = let final dynamic #t30 = self::f<dynamic>() in let final dynamic #t31 = this.[](#t30) in let final dynamic #t32 = this.[]=(#t30, #t31.-(1)) in #t31;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.transformed.expect
new file mode 100644
index 0000000..754dfc6
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this.dart.strong.transformed.expect
@@ -0,0 +1,59 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Index extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::Index i) → self::B
+    return null;
+  operator []=(self::Index i, self::B v) → void {}
+  method test() → void {
+    this.{self::Test::[]=}(self::f<dynamic>() as{TypeError} self::Index, self::f<self::B>());
+    let final dynamic #t1 = self::f<dynamic>() in this.{self::Test::[]}(#t1 as{TypeError} self::Index).{core::Object::==}(null) ?{self::B} let final self::B #t2 = self::f<self::B>() in let final void #t3 = this.{self::Test::[]=}(#t1 as{TypeError} self::Index, #t2) in #t2 : null;
+    let final dynamic #t4 = self::f<dynamic>() in this.{self::Test::[]=}(#t4 as{TypeError} self::Index, this.{self::Test::[]}(#t4 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B);
+    let final dynamic #t5 = self::f<dynamic>() in this.{self::Test::[]=}(#t5 as{TypeError} self::Index, this.{self::Test::[]}(#t5 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B));
+    let final dynamic #t6 = self::f<dynamic>() in this.{self::Test::[]=}(#t6 as{TypeError} self::Index, this.{self::Test::[]}(#t6 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A));
+    let final dynamic #t7 = self::f<dynamic>() in let final self::B #t8 = this.{self::Test::[]}(#t7 as{TypeError} self::Index).{self::B::-}(1) in let final void #t9 = this.{self::Test::[]=}(#t7 as{TypeError} self::Index, #t8) in #t8;
+    let final dynamic #t10 = self::f<dynamic>() in this.{self::Test::[]=}(#t10 as{TypeError} self::Index, this.{self::Test::[]}(#t10 as{TypeError} self::Index).{self::B::-}(1));
+    self::B v1 = let final dynamic #t11 = self::f<dynamic>() in let final self::B #t12 = self::f<self::B>() in let final void #t13 = this.{self::Test::[]=}(#t11 as{TypeError} self::Index, #t12) in #t12;
+    self::B v2 = let final dynamic #t14 = self::f<dynamic>() in let final self::B #t15 = this.{self::Test::[]}(#t14 as{TypeError} self::Index) in #t15.{core::Object::==}(null) ?{self::B} let final self::B #t16 = self::f<self::B>() in let final void #t17 = this.{self::Test::[]=}(#t14 as{TypeError} self::Index, #t16) in #t16 : #t15;
+    self::A v3 = let final dynamic #t18 = self::f<dynamic>() in let final self::A #t19 = this.{self::Test::[]}(#t18 as{TypeError} self::Index).{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B in let final void #t20 = this.{self::Test::[]=}(#t18 as{TypeError} self::Index, #t19) in #t19;
+    self::B v4 = let final dynamic #t21 = self::f<dynamic>() in let final self::B #t22 = this.{self::Test::[]}(#t21 as{TypeError} self::Index).{self::B::*}(self::f<dynamic>() as{TypeError} self::B) in let final void #t23 = this.{self::Test::[]=}(#t21 as{TypeError} self::Index, #t22) in #t22;
+    self::C v5 = let final dynamic #t24 = self::f<dynamic>() in let final self::C #t25 = this.{self::Test::[]}(#t24 as{TypeError} self::Index).{self::B::&}(self::f<dynamic>() as{TypeError} self::A) in let final void #t26 = this.{self::Test::[]=}(#t24 as{TypeError} self::Index, #t25) in #t25;
+    self::B v6 = let final dynamic #t27 = self::f<dynamic>() in let final self::B #t28 = this.{self::Test::[]}(#t27 as{TypeError} self::Index).{self::B::-}(1) in let final void #t29 = this.{self::Test::[]=}(#t27 as{TypeError} self::Index, #t28) in #t28;
+    self::B v7 = let final dynamic #t30 = self::f<dynamic>() in let final self::B #t31 = this.{self::Test::[]}(#t30 as{TypeError} self::Index) in let final void #t32 = this.{self::Test::[]=}(#t30 as{TypeError} self::Index, #t31.{self::B::-}(1)) in #t31;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..62118c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_this_upwards.dart.direct.transformed.expect
@@ -0,0 +1,176 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class Test1 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract operator [](core::String s) → core::int;
+  abstract operator []=(core::String s, core::int v) → void;
+  method test() → void {
+    dynamic v1 = let final dynamic #t1 = "x" in let final dynamic #t2 = self::getInt() in let final dynamic #t3 = this.[]=(#t1, #t2) in #t2;
+    dynamic v2 = let final dynamic #t4 = "x" in let final dynamic #t5 = self::getNum() in let final dynamic #t6 = this.[]=(#t4, #t5) in #t5;
+    dynamic v4 = let final dynamic #t7 = "x" in let final dynamic #t8 = this.[](#t7) in #t8.==(null) ? let final dynamic #t9 = self::getInt() in let final dynamic #t10 = this.[]=(#t7, #t9) in #t9 : #t8;
+    dynamic v5 = let final dynamic #t11 = "x" in let final dynamic #t12 = this.[](#t11) in #t12.==(null) ? let final dynamic #t13 = self::getNum() in let final dynamic #t14 = this.[]=(#t11, #t13) in #t13 : #t12;
+    dynamic v7 = let final dynamic #t15 = "x" in let final dynamic #t16 = this.[](#t15).+(self::getInt()) in let final dynamic #t17 = this.[]=(#t15, #t16) in #t16;
+    dynamic v8 = let final dynamic #t18 = "x" in let final dynamic #t19 = this.[](#t18).+(self::getNum()) in let final dynamic #t20 = this.[]=(#t18, #t19) in #t19;
+    dynamic v10 = let final dynamic #t21 = "x" in let final dynamic #t22 = this.[](#t21).+(1) in let final dynamic #t23 = this.[]=(#t21, #t22) in #t22;
+    dynamic v11 = let final dynamic #t24 = "x" in let final dynamic #t25 = this.[](#t24) in let final dynamic #t26 = this.[]=(#t24, #t25.+(1)) in #t25;
+  }
+}
+abstract class Test2 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract operator [](core::String s) → core::int;
+  abstract operator []=(core::String s, core::num v) → void;
+  method test() → void {
+    dynamic v1 = let final dynamic #t27 = "x" in let final dynamic #t28 = self::getInt() in let final dynamic #t29 = this.[]=(#t27, #t28) in #t28;
+    dynamic v2 = let final dynamic #t30 = "x" in let final dynamic #t31 = self::getNum() in let final dynamic #t32 = this.[]=(#t30, #t31) in #t31;
+    dynamic v3 = let final dynamic #t33 = "x" in let final dynamic #t34 = self::getDouble() in let final dynamic #t35 = this.[]=(#t33, #t34) in #t34;
+    dynamic v4 = let final dynamic #t36 = "x" in let final dynamic #t37 = this.[](#t36) in #t37.==(null) ? let final dynamic #t38 = self::getInt() in let final dynamic #t39 = this.[]=(#t36, #t38) in #t38 : #t37;
+    dynamic v5 = let final dynamic #t40 = "x" in let final dynamic #t41 = this.[](#t40) in #t41.==(null) ? let final dynamic #t42 = self::getNum() in let final dynamic #t43 = this.[]=(#t40, #t42) in #t42 : #t41;
+    dynamic v6 = let final dynamic #t44 = "x" in let final dynamic #t45 = this.[](#t44) in #t45.==(null) ? let final dynamic #t46 = self::getDouble() in let final dynamic #t47 = this.[]=(#t44, #t46) in #t46 : #t45;
+    dynamic v7 = let final dynamic #t48 = "x" in let final dynamic #t49 = this.[](#t48).+(self::getInt()) in let final dynamic #t50 = this.[]=(#t48, #t49) in #t49;
+    dynamic v8 = let final dynamic #t51 = "x" in let final dynamic #t52 = this.[](#t51).+(self::getNum()) in let final dynamic #t53 = this.[]=(#t51, #t52) in #t52;
+    dynamic v9 = let final dynamic #t54 = "x" in let final dynamic #t55 = this.[](#t54).+(self::getDouble()) in let final dynamic #t56 = this.[]=(#t54, #t55) in #t55;
+    dynamic v10 = let final dynamic #t57 = "x" in let final dynamic #t58 = this.[](#t57).+(1) in let final dynamic #t59 = this.[]=(#t57, #t58) in #t58;
+    dynamic v11 = let final dynamic #t60 = "x" in let final dynamic #t61 = this.[](#t60) in let final dynamic #t62 = this.[]=(#t60, #t61.+(1)) in #t61;
+  }
+}
+abstract class Test3 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract operator [](core::String s) → core::int;
+  abstract operator []=(core::String s, core::double v) → void;
+  method test() → void {
+    dynamic v2 = let final dynamic #t63 = "x" in let final dynamic #t64 = self::getNum() in let final dynamic #t65 = this.[]=(#t63, #t64) in #t64;
+    dynamic v3 = let final dynamic #t66 = "x" in let final dynamic #t67 = self::getDouble() in let final dynamic #t68 = this.[]=(#t66, #t67) in #t67;
+    dynamic v5 = let final dynamic #t69 = "x" in let final dynamic #t70 = this.[](#t69) in #t70.==(null) ? let final dynamic #t71 = self::getNum() in let final dynamic #t72 = this.[]=(#t69, #t71) in #t71 : #t70;
+    dynamic v6 = let final dynamic #t73 = "x" in let final dynamic #t74 = this.[](#t73) in #t74.==(null) ? let final dynamic #t75 = self::getDouble() in let final dynamic #t76 = this.[]=(#t73, #t75) in #t75 : #t74;
+    dynamic v7 = let final dynamic #t77 = "x" in let final dynamic #t78 = this.[](#t77).+(self::getInt()) in let final dynamic #t79 = this.[]=(#t77, #t78) in #t78;
+    dynamic v8 = let final dynamic #t80 = "x" in let final dynamic #t81 = this.[](#t80).+(self::getNum()) in let final dynamic #t82 = this.[]=(#t80, #t81) in #t81;
+    dynamic v9 = let final dynamic #t83 = "x" in let final dynamic #t84 = this.[](#t83).+(self::getDouble()) in let final dynamic #t85 = this.[]=(#t83, #t84) in #t84;
+    dynamic v10 = let final dynamic #t86 = "x" in let final dynamic #t87 = this.[](#t86).+(1) in let final dynamic #t88 = this.[]=(#t86, #t87) in #t87;
+    dynamic v11 = let final dynamic #t89 = "x" in let final dynamic #t90 = this.[](#t89) in let final dynamic #t91 = this.[]=(#t89, #t90.+(1)) in #t90;
+  }
+}
+abstract class Test4 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract operator [](core::String s) → core::num;
+  abstract operator []=(core::String s, core::int v) → void;
+  method test() → void {
+    dynamic v1 = let final dynamic #t92 = "x" in let final dynamic #t93 = self::getInt() in let final dynamic #t94 = this.[]=(#t92, #t93) in #t93;
+    dynamic v2 = let final dynamic #t95 = "x" in let final dynamic #t96 = self::getNum() in let final dynamic #t97 = this.[]=(#t95, #t96) in #t96;
+    dynamic v4 = let final dynamic #t98 = "x" in let final dynamic #t99 = this.[](#t98) in #t99.==(null) ? let final dynamic #t100 = self::getInt() in let final dynamic #t101 = this.[]=(#t98, #t100) in #t100 : #t99;
+    dynamic v5 = let final dynamic #t102 = "x" in let final dynamic #t103 = this.[](#t102) in #t103.==(null) ? let final dynamic #t104 = self::getNum() in let final dynamic #t105 = this.[]=(#t102, #t104) in #t104 : #t103;
+    dynamic v7 = let final dynamic #t106 = "x" in let final dynamic #t107 = this.[](#t106).+(self::getInt()) in let final dynamic #t108 = this.[]=(#t106, #t107) in #t107;
+    dynamic v8 = let final dynamic #t109 = "x" in let final dynamic #t110 = this.[](#t109).+(self::getNum()) in let final dynamic #t111 = this.[]=(#t109, #t110) in #t110;
+    dynamic v10 = let final dynamic #t112 = "x" in let final dynamic #t113 = this.[](#t112).+(1) in let final dynamic #t114 = this.[]=(#t112, #t113) in #t113;
+    dynamic v11 = let final dynamic #t115 = "x" in let final dynamic #t116 = this.[](#t115) in let final dynamic #t117 = this.[]=(#t115, #t116.+(1)) in #t116;
+  }
+}
+abstract class Test5 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract operator [](core::String s) → core::num;
+  abstract operator []=(core::String s, core::num v) → void;
+  method test() → void {
+    dynamic v1 = let final dynamic #t118 = "x" in let final dynamic #t119 = self::getInt() in let final dynamic #t120 = this.[]=(#t118, #t119) in #t119;
+    dynamic v2 = let final dynamic #t121 = "x" in let final dynamic #t122 = self::getNum() in let final dynamic #t123 = this.[]=(#t121, #t122) in #t122;
+    dynamic v3 = let final dynamic #t124 = "x" in let final dynamic #t125 = self::getDouble() in let final dynamic #t126 = this.[]=(#t124, #t125) in #t125;
+    dynamic v4 = let final dynamic #t127 = "x" in let final dynamic #t128 = this.[](#t127) in #t128.==(null) ? let final dynamic #t129 = self::getInt() in let final dynamic #t130 = this.[]=(#t127, #t129) in #t129 : #t128;
+    dynamic v5 = let final dynamic #t131 = "x" in let final dynamic #t132 = this.[](#t131) in #t132.==(null) ? let final dynamic #t133 = self::getNum() in let final dynamic #t134 = this.[]=(#t131, #t133) in #t133 : #t132;
+    dynamic v6 = let final dynamic #t135 = "x" in let final dynamic #t136 = this.[](#t135) in #t136.==(null) ? let final dynamic #t137 = self::getDouble() in let final dynamic #t138 = this.[]=(#t135, #t137) in #t137 : #t136;
+    dynamic v7 = let final dynamic #t139 = "x" in let final dynamic #t140 = this.[](#t139).+(self::getInt()) in let final dynamic #t141 = this.[]=(#t139, #t140) in #t140;
+    dynamic v8 = let final dynamic #t142 = "x" in let final dynamic #t143 = this.[](#t142).+(self::getNum()) in let final dynamic #t144 = this.[]=(#t142, #t143) in #t143;
+    dynamic v9 = let final dynamic #t145 = "x" in let final dynamic #t146 = this.[](#t145).+(self::getDouble()) in let final dynamic #t147 = this.[]=(#t145, #t146) in #t146;
+    dynamic v10 = let final dynamic #t148 = "x" in let final dynamic #t149 = this.[](#t148).+(1) in let final dynamic #t150 = this.[]=(#t148, #t149) in #t149;
+    dynamic v11 = let final dynamic #t151 = "x" in let final dynamic #t152 = this.[](#t151) in let final dynamic #t153 = this.[]=(#t151, #t152.+(1)) in #t152;
+  }
+}
+abstract class Test6 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract operator [](core::String s) → core::num;
+  abstract operator []=(core::String s, core::double v) → void;
+  method test() → void {
+    dynamic v2 = let final dynamic #t154 = "x" in let final dynamic #t155 = self::getNum() in let final dynamic #t156 = this.[]=(#t154, #t155) in #t155;
+    dynamic v3 = let final dynamic #t157 = "x" in let final dynamic #t158 = self::getDouble() in let final dynamic #t159 = this.[]=(#t157, #t158) in #t158;
+    dynamic v5 = let final dynamic #t160 = "x" in let final dynamic #t161 = this.[](#t160) in #t161.==(null) ? let final dynamic #t162 = self::getNum() in let final dynamic #t163 = this.[]=(#t160, #t162) in #t162 : #t161;
+    dynamic v6 = let final dynamic #t164 = "x" in let final dynamic #t165 = this.[](#t164) in #t165.==(null) ? let final dynamic #t166 = self::getDouble() in let final dynamic #t167 = this.[]=(#t164, #t166) in #t166 : #t165;
+    dynamic v7 = let final dynamic #t168 = "x" in let final dynamic #t169 = this.[](#t168).+(self::getInt()) in let final dynamic #t170 = this.[]=(#t168, #t169) in #t169;
+    dynamic v8 = let final dynamic #t171 = "x" in let final dynamic #t172 = this.[](#t171).+(self::getNum()) in let final dynamic #t173 = this.[]=(#t171, #t172) in #t172;
+    dynamic v9 = let final dynamic #t174 = "x" in let final dynamic #t175 = this.[](#t174).+(self::getDouble()) in let final dynamic #t176 = this.[]=(#t174, #t175) in #t175;
+    dynamic v10 = let final dynamic #t177 = "x" in let final dynamic #t178 = this.[](#t177).+(1) in let final dynamic #t179 = this.[]=(#t177, #t178) in #t178;
+    dynamic v11 = let final dynamic #t180 = "x" in let final dynamic #t181 = this.[](#t180) in let final dynamic #t182 = this.[]=(#t180, #t181.+(1)) in #t181;
+  }
+}
+abstract class Test7 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract operator [](core::String s) → core::double;
+  abstract operator []=(core::String s, core::int v) → void;
+  method test() → void {
+    dynamic v1 = let final dynamic #t183 = "x" in let final dynamic #t184 = self::getInt() in let final dynamic #t185 = this.[]=(#t183, #t184) in #t184;
+    dynamic v2 = let final dynamic #t186 = "x" in let final dynamic #t187 = self::getNum() in let final dynamic #t188 = this.[]=(#t186, #t187) in #t187;
+    dynamic v4 = let final dynamic #t189 = "x" in let final dynamic #t190 = this.[](#t189) in #t190.==(null) ? let final dynamic #t191 = self::getInt() in let final dynamic #t192 = this.[]=(#t189, #t191) in #t191 : #t190;
+    dynamic v5 = let final dynamic #t193 = "x" in let final dynamic #t194 = this.[](#t193) in #t194.==(null) ? let final dynamic #t195 = self::getNum() in let final dynamic #t196 = this.[]=(#t193, #t195) in #t195 : #t194;
+    dynamic v7 = let final dynamic #t197 = "x" in let final dynamic #t198 = this.[](#t197).+(self::getInt()) in let final dynamic #t199 = this.[]=(#t197, #t198) in #t198;
+    dynamic v8 = let final dynamic #t200 = "x" in let final dynamic #t201 = this.[](#t200).+(self::getNum()) in let final dynamic #t202 = this.[]=(#t200, #t201) in #t201;
+    dynamic v10 = let final dynamic #t203 = "x" in let final dynamic #t204 = this.[](#t203).+(1) in let final dynamic #t205 = this.[]=(#t203, #t204) in #t204;
+    dynamic v11 = let final dynamic #t206 = "x" in let final dynamic #t207 = this.[](#t206) in let final dynamic #t208 = this.[]=(#t206, #t207.+(1)) in #t207;
+  }
+}
+abstract class Test8 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract operator [](core::String s) → core::double;
+  abstract operator []=(core::String s, core::num v) → void;
+  method test() → void {
+    dynamic v1 = let final dynamic #t209 = "x" in let final dynamic #t210 = self::getInt() in let final dynamic #t211 = this.[]=(#t209, #t210) in #t210;
+    dynamic v2 = let final dynamic #t212 = "x" in let final dynamic #t213 = self::getNum() in let final dynamic #t214 = this.[]=(#t212, #t213) in #t213;
+    dynamic v3 = let final dynamic #t215 = "x" in let final dynamic #t216 = self::getDouble() in let final dynamic #t217 = this.[]=(#t215, #t216) in #t216;
+    dynamic v4 = let final dynamic #t218 = "x" in let final dynamic #t219 = this.[](#t218) in #t219.==(null) ? let final dynamic #t220 = self::getInt() in let final dynamic #t221 = this.[]=(#t218, #t220) in #t220 : #t219;
+    dynamic v5 = let final dynamic #t222 = "x" in let final dynamic #t223 = this.[](#t222) in #t223.==(null) ? let final dynamic #t224 = self::getNum() in let final dynamic #t225 = this.[]=(#t222, #t224) in #t224 : #t223;
+    dynamic v6 = let final dynamic #t226 = "x" in let final dynamic #t227 = this.[](#t226) in #t227.==(null) ? let final dynamic #t228 = self::getDouble() in let final dynamic #t229 = this.[]=(#t226, #t228) in #t228 : #t227;
+    dynamic v7 = let final dynamic #t230 = "x" in let final dynamic #t231 = this.[](#t230).+(self::getInt()) in let final dynamic #t232 = this.[]=(#t230, #t231) in #t231;
+    dynamic v8 = let final dynamic #t233 = "x" in let final dynamic #t234 = this.[](#t233).+(self::getNum()) in let final dynamic #t235 = this.[]=(#t233, #t234) in #t234;
+    dynamic v9 = let final dynamic #t236 = "x" in let final dynamic #t237 = this.[](#t236).+(self::getDouble()) in let final dynamic #t238 = this.[]=(#t236, #t237) in #t237;
+    dynamic v10 = let final dynamic #t239 = "x" in let final dynamic #t240 = this.[](#t239).+(1) in let final dynamic #t241 = this.[]=(#t239, #t240) in #t240;
+    dynamic v11 = let final dynamic #t242 = "x" in let final dynamic #t243 = this.[](#t242) in let final dynamic #t244 = this.[]=(#t242, #t243.+(1)) in #t243;
+  }
+}
+abstract class Test9 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract operator [](core::String s) → core::double;
+  abstract operator []=(core::String s, core::double v) → void;
+  method test() → void {
+    dynamic v2 = let final dynamic #t245 = "x" in let final dynamic #t246 = self::getNum() in let final dynamic #t247 = this.[]=(#t245, #t246) in #t246;
+    dynamic v3 = let final dynamic #t248 = "x" in let final dynamic #t249 = self::getDouble() in let final dynamic #t250 = this.[]=(#t248, #t249) in #t249;
+    dynamic v5 = let final dynamic #t251 = "x" in let final dynamic #t252 = this.[](#t251) in #t252.==(null) ? let final dynamic #t253 = self::getNum() in let final dynamic #t254 = this.[]=(#t251, #t253) in #t253 : #t252;
+    dynamic v6 = let final dynamic #t255 = "x" in let final dynamic #t256 = this.[](#t255) in #t256.==(null) ? let final dynamic #t257 = self::getDouble() in let final dynamic #t258 = this.[]=(#t255, #t257) in #t257 : #t256;
+    dynamic v7 = let final dynamic #t259 = "x" in let final dynamic #t260 = this.[](#t259).+(self::getInt()) in let final dynamic #t261 = this.[]=(#t259, #t260) in #t260;
+    dynamic v8 = let final dynamic #t262 = "x" in let final dynamic #t263 = this.[](#t262).+(self::getNum()) in let final dynamic #t264 = this.[]=(#t262, #t263) in #t263;
+    dynamic v9 = let final dynamic #t265 = "x" in let final dynamic #t266 = this.[](#t265).+(self::getDouble()) in let final dynamic #t267 = this.[]=(#t265, #t266) in #t266;
+    dynamic v10 = let final dynamic #t268 = "x" in let final dynamic #t269 = this.[](#t268).+(1) in let final dynamic #t270 = this.[]=(#t268, #t269) in #t269;
+    dynamic v11 = let final dynamic #t271 = "x" in let final dynamic #t272 = this.[](#t271) in let final dynamic #t273 = this.[]=(#t271, #t272.+(1)) in #t272;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..7455ebf
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_index_upwards.dart.direct.transformed.expect
@@ -0,0 +1,120 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class Test<T extends core::Object, U extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract operator [](core::String s) → self::Test::T;
+  abstract operator []=(core::String s, self::Test::U v) → void;
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method test1(self::Test<core::int, core::int> t) → void {
+  dynamic v1 = let final dynamic #t1 = t in let final dynamic #t2 = "x" in let final dynamic #t3 = self::getInt() in let final dynamic #t4 = #t1.[]=(#t2, #t3) in #t3;
+  dynamic v2 = let final dynamic #t5 = t in let final dynamic #t6 = "x" in let final dynamic #t7 = self::getNum() in let final dynamic #t8 = #t5.[]=(#t6, #t7) in #t7;
+  dynamic v4 = let final dynamic #t9 = t in let final dynamic #t10 = "x" in let final dynamic #t11 = #t9.[](#t10) in #t11.==(null) ? let final dynamic #t12 = self::getInt() in let final dynamic #t13 = #t9.[]=(#t10, #t12) in #t12 : #t11;
+  dynamic v5 = let final dynamic #t14 = t in let final dynamic #t15 = "x" in let final dynamic #t16 = #t14.[](#t15) in #t16.==(null) ? let final dynamic #t17 = self::getNum() in let final dynamic #t18 = #t14.[]=(#t15, #t17) in #t17 : #t16;
+  dynamic v7 = let final dynamic #t19 = t in let final dynamic #t20 = "x" in let final dynamic #t21 = #t19.[](#t20).+(self::getInt()) in let final dynamic #t22 = #t19.[]=(#t20, #t21) in #t21;
+  dynamic v8 = let final dynamic #t23 = t in let final dynamic #t24 = "x" in let final dynamic #t25 = #t23.[](#t24).+(self::getNum()) in let final dynamic #t26 = #t23.[]=(#t24, #t25) in #t25;
+  dynamic v10 = let final dynamic #t27 = t in let final dynamic #t28 = "x" in let final dynamic #t29 = #t27.[](#t28).+(1) in let final dynamic #t30 = #t27.[]=(#t28, #t29) in #t29;
+  dynamic v11 = let final dynamic #t31 = t in let final dynamic #t32 = "x" in let final dynamic #t33 = #t31.[](#t32) in let final dynamic #t34 = #t31.[]=(#t32, #t33.+(1)) in #t33;
+}
+static method test2(self::Test<core::int, core::num> t) → void {
+  dynamic v1 = let final dynamic #t35 = t in let final dynamic #t36 = "x" in let final dynamic #t37 = self::getInt() in let final dynamic #t38 = #t35.[]=(#t36, #t37) in #t37;
+  dynamic v2 = let final dynamic #t39 = t in let final dynamic #t40 = "x" in let final dynamic #t41 = self::getNum() in let final dynamic #t42 = #t39.[]=(#t40, #t41) in #t41;
+  dynamic v3 = let final dynamic #t43 = t in let final dynamic #t44 = "x" in let final dynamic #t45 = self::getDouble() in let final dynamic #t46 = #t43.[]=(#t44, #t45) in #t45;
+  dynamic v4 = let final dynamic #t47 = t in let final dynamic #t48 = "x" in let final dynamic #t49 = #t47.[](#t48) in #t49.==(null) ? let final dynamic #t50 = self::getInt() in let final dynamic #t51 = #t47.[]=(#t48, #t50) in #t50 : #t49;
+  dynamic v5 = let final dynamic #t52 = t in let final dynamic #t53 = "x" in let final dynamic #t54 = #t52.[](#t53) in #t54.==(null) ? let final dynamic #t55 = self::getNum() in let final dynamic #t56 = #t52.[]=(#t53, #t55) in #t55 : #t54;
+  dynamic v6 = let final dynamic #t57 = t in let final dynamic #t58 = "x" in let final dynamic #t59 = #t57.[](#t58) in #t59.==(null) ? let final dynamic #t60 = self::getDouble() in let final dynamic #t61 = #t57.[]=(#t58, #t60) in #t60 : #t59;
+  dynamic v7 = let final dynamic #t62 = t in let final dynamic #t63 = "x" in let final dynamic #t64 = #t62.[](#t63).+(self::getInt()) in let final dynamic #t65 = #t62.[]=(#t63, #t64) in #t64;
+  dynamic v8 = let final dynamic #t66 = t in let final dynamic #t67 = "x" in let final dynamic #t68 = #t66.[](#t67).+(self::getNum()) in let final dynamic #t69 = #t66.[]=(#t67, #t68) in #t68;
+  dynamic v9 = let final dynamic #t70 = t in let final dynamic #t71 = "x" in let final dynamic #t72 = #t70.[](#t71).+(self::getDouble()) in let final dynamic #t73 = #t70.[]=(#t71, #t72) in #t72;
+  dynamic v10 = let final dynamic #t74 = t in let final dynamic #t75 = "x" in let final dynamic #t76 = #t74.[](#t75).+(1) in let final dynamic #t77 = #t74.[]=(#t75, #t76) in #t76;
+  dynamic v11 = let final dynamic #t78 = t in let final dynamic #t79 = "x" in let final dynamic #t80 = #t78.[](#t79) in let final dynamic #t81 = #t78.[]=(#t79, #t80.+(1)) in #t80;
+}
+static method test3(self::Test<core::int, core::double> t) → void {
+  dynamic v2 = let final dynamic #t82 = t in let final dynamic #t83 = "x" in let final dynamic #t84 = self::getNum() in let final dynamic #t85 = #t82.[]=(#t83, #t84) in #t84;
+  dynamic v3 = let final dynamic #t86 = t in let final dynamic #t87 = "x" in let final dynamic #t88 = self::getDouble() in let final dynamic #t89 = #t86.[]=(#t87, #t88) in #t88;
+  dynamic v5 = let final dynamic #t90 = t in let final dynamic #t91 = "x" in let final dynamic #t92 = #t90.[](#t91) in #t92.==(null) ? let final dynamic #t93 = self::getNum() in let final dynamic #t94 = #t90.[]=(#t91, #t93) in #t93 : #t92;
+  dynamic v6 = let final dynamic #t95 = t in let final dynamic #t96 = "x" in let final dynamic #t97 = #t95.[](#t96) in #t97.==(null) ? let final dynamic #t98 = self::getDouble() in let final dynamic #t99 = #t95.[]=(#t96, #t98) in #t98 : #t97;
+  dynamic v7 = let final dynamic #t100 = t in let final dynamic #t101 = "x" in let final dynamic #t102 = #t100.[](#t101).+(self::getInt()) in let final dynamic #t103 = #t100.[]=(#t101, #t102) in #t102;
+  dynamic v8 = let final dynamic #t104 = t in let final dynamic #t105 = "x" in let final dynamic #t106 = #t104.[](#t105).+(self::getNum()) in let final dynamic #t107 = #t104.[]=(#t105, #t106) in #t106;
+  dynamic v9 = let final dynamic #t108 = t in let final dynamic #t109 = "x" in let final dynamic #t110 = #t108.[](#t109).+(self::getDouble()) in let final dynamic #t111 = #t108.[]=(#t109, #t110) in #t110;
+  dynamic v10 = let final dynamic #t112 = t in let final dynamic #t113 = "x" in let final dynamic #t114 = #t112.[](#t113).+(1) in let final dynamic #t115 = #t112.[]=(#t113, #t114) in #t114;
+  dynamic v11 = let final dynamic #t116 = t in let final dynamic #t117 = "x" in let final dynamic #t118 = #t116.[](#t117) in let final dynamic #t119 = #t116.[]=(#t117, #t118.+(1)) in #t118;
+}
+static method test4(self::Test<core::num, core::int> t) → void {
+  dynamic v1 = let final dynamic #t120 = t in let final dynamic #t121 = "x" in let final dynamic #t122 = self::getInt() in let final dynamic #t123 = #t120.[]=(#t121, #t122) in #t122;
+  dynamic v2 = let final dynamic #t124 = t in let final dynamic #t125 = "x" in let final dynamic #t126 = self::getNum() in let final dynamic #t127 = #t124.[]=(#t125, #t126) in #t126;
+  dynamic v4 = let final dynamic #t128 = t in let final dynamic #t129 = "x" in let final dynamic #t130 = #t128.[](#t129) in #t130.==(null) ? let final dynamic #t131 = self::getInt() in let final dynamic #t132 = #t128.[]=(#t129, #t131) in #t131 : #t130;
+  dynamic v5 = let final dynamic #t133 = t in let final dynamic #t134 = "x" in let final dynamic #t135 = #t133.[](#t134) in #t135.==(null) ? let final dynamic #t136 = self::getNum() in let final dynamic #t137 = #t133.[]=(#t134, #t136) in #t136 : #t135;
+  dynamic v7 = let final dynamic #t138 = t in let final dynamic #t139 = "x" in let final dynamic #t140 = #t138.[](#t139).+(self::getInt()) in let final dynamic #t141 = #t138.[]=(#t139, #t140) in #t140;
+  dynamic v8 = let final dynamic #t142 = t in let final dynamic #t143 = "x" in let final dynamic #t144 = #t142.[](#t143).+(self::getNum()) in let final dynamic #t145 = #t142.[]=(#t143, #t144) in #t144;
+  dynamic v10 = let final dynamic #t146 = t in let final dynamic #t147 = "x" in let final dynamic #t148 = #t146.[](#t147).+(1) in let final dynamic #t149 = #t146.[]=(#t147, #t148) in #t148;
+  dynamic v11 = let final dynamic #t150 = t in let final dynamic #t151 = "x" in let final dynamic #t152 = #t150.[](#t151) in let final dynamic #t153 = #t150.[]=(#t151, #t152.+(1)) in #t152;
+}
+static method test5(self::Test<core::num, core::num> t) → void {
+  dynamic v1 = let final dynamic #t154 = t in let final dynamic #t155 = "x" in let final dynamic #t156 = self::getInt() in let final dynamic #t157 = #t154.[]=(#t155, #t156) in #t156;
+  dynamic v2 = let final dynamic #t158 = t in let final dynamic #t159 = "x" in let final dynamic #t160 = self::getNum() in let final dynamic #t161 = #t158.[]=(#t159, #t160) in #t160;
+  dynamic v3 = let final dynamic #t162 = t in let final dynamic #t163 = "x" in let final dynamic #t164 = self::getDouble() in let final dynamic #t165 = #t162.[]=(#t163, #t164) in #t164;
+  dynamic v4 = let final dynamic #t166 = t in let final dynamic #t167 = "x" in let final dynamic #t168 = #t166.[](#t167) in #t168.==(null) ? let final dynamic #t169 = self::getInt() in let final dynamic #t170 = #t166.[]=(#t167, #t169) in #t169 : #t168;
+  dynamic v5 = let final dynamic #t171 = t in let final dynamic #t172 = "x" in let final dynamic #t173 = #t171.[](#t172) in #t173.==(null) ? let final dynamic #t174 = self::getNum() in let final dynamic #t175 = #t171.[]=(#t172, #t174) in #t174 : #t173;
+  dynamic v6 = let final dynamic #t176 = t in let final dynamic #t177 = "x" in let final dynamic #t178 = #t176.[](#t177) in #t178.==(null) ? let final dynamic #t179 = self::getDouble() in let final dynamic #t180 = #t176.[]=(#t177, #t179) in #t179 : #t178;
+  dynamic v7 = let final dynamic #t181 = t in let final dynamic #t182 = "x" in let final dynamic #t183 = #t181.[](#t182).+(self::getInt()) in let final dynamic #t184 = #t181.[]=(#t182, #t183) in #t183;
+  dynamic v8 = let final dynamic #t185 = t in let final dynamic #t186 = "x" in let final dynamic #t187 = #t185.[](#t186).+(self::getNum()) in let final dynamic #t188 = #t185.[]=(#t186, #t187) in #t187;
+  dynamic v9 = let final dynamic #t189 = t in let final dynamic #t190 = "x" in let final dynamic #t191 = #t189.[](#t190).+(self::getDouble()) in let final dynamic #t192 = #t189.[]=(#t190, #t191) in #t191;
+  dynamic v10 = let final dynamic #t193 = t in let final dynamic #t194 = "x" in let final dynamic #t195 = #t193.[](#t194).+(1) in let final dynamic #t196 = #t193.[]=(#t194, #t195) in #t195;
+  dynamic v11 = let final dynamic #t197 = t in let final dynamic #t198 = "x" in let final dynamic #t199 = #t197.[](#t198) in let final dynamic #t200 = #t197.[]=(#t198, #t199.+(1)) in #t199;
+}
+static method test6(self::Test<core::num, core::double> t) → void {
+  dynamic v2 = let final dynamic #t201 = t in let final dynamic #t202 = "x" in let final dynamic #t203 = self::getNum() in let final dynamic #t204 = #t201.[]=(#t202, #t203) in #t203;
+  dynamic v3 = let final dynamic #t205 = t in let final dynamic #t206 = "x" in let final dynamic #t207 = self::getDouble() in let final dynamic #t208 = #t205.[]=(#t206, #t207) in #t207;
+  dynamic v5 = let final dynamic #t209 = t in let final dynamic #t210 = "x" in let final dynamic #t211 = #t209.[](#t210) in #t211.==(null) ? let final dynamic #t212 = self::getNum() in let final dynamic #t213 = #t209.[]=(#t210, #t212) in #t212 : #t211;
+  dynamic v6 = let final dynamic #t214 = t in let final dynamic #t215 = "x" in let final dynamic #t216 = #t214.[](#t215) in #t216.==(null) ? let final dynamic #t217 = self::getDouble() in let final dynamic #t218 = #t214.[]=(#t215, #t217) in #t217 : #t216;
+  dynamic v7 = let final dynamic #t219 = t in let final dynamic #t220 = "x" in let final dynamic #t221 = #t219.[](#t220).+(self::getInt()) in let final dynamic #t222 = #t219.[]=(#t220, #t221) in #t221;
+  dynamic v8 = let final dynamic #t223 = t in let final dynamic #t224 = "x" in let final dynamic #t225 = #t223.[](#t224).+(self::getNum()) in let final dynamic #t226 = #t223.[]=(#t224, #t225) in #t225;
+  dynamic v9 = let final dynamic #t227 = t in let final dynamic #t228 = "x" in let final dynamic #t229 = #t227.[](#t228).+(self::getDouble()) in let final dynamic #t230 = #t227.[]=(#t228, #t229) in #t229;
+  dynamic v10 = let final dynamic #t231 = t in let final dynamic #t232 = "x" in let final dynamic #t233 = #t231.[](#t232).+(1) in let final dynamic #t234 = #t231.[]=(#t232, #t233) in #t233;
+  dynamic v11 = let final dynamic #t235 = t in let final dynamic #t236 = "x" in let final dynamic #t237 = #t235.[](#t236) in let final dynamic #t238 = #t235.[]=(#t236, #t237.+(1)) in #t237;
+}
+static method test7(self::Test<core::double, core::int> t) → void {
+  dynamic v1 = let final dynamic #t239 = t in let final dynamic #t240 = "x" in let final dynamic #t241 = self::getInt() in let final dynamic #t242 = #t239.[]=(#t240, #t241) in #t241;
+  dynamic v2 = let final dynamic #t243 = t in let final dynamic #t244 = "x" in let final dynamic #t245 = self::getNum() in let final dynamic #t246 = #t243.[]=(#t244, #t245) in #t245;
+  dynamic v4 = let final dynamic #t247 = t in let final dynamic #t248 = "x" in let final dynamic #t249 = #t247.[](#t248) in #t249.==(null) ? let final dynamic #t250 = self::getInt() in let final dynamic #t251 = #t247.[]=(#t248, #t250) in #t250 : #t249;
+  dynamic v5 = let final dynamic #t252 = t in let final dynamic #t253 = "x" in let final dynamic #t254 = #t252.[](#t253) in #t254.==(null) ? let final dynamic #t255 = self::getNum() in let final dynamic #t256 = #t252.[]=(#t253, #t255) in #t255 : #t254;
+  dynamic v7 = let final dynamic #t257 = t in let final dynamic #t258 = "x" in let final dynamic #t259 = #t257.[](#t258).+(self::getInt()) in let final dynamic #t260 = #t257.[]=(#t258, #t259) in #t259;
+  dynamic v8 = let final dynamic #t261 = t in let final dynamic #t262 = "x" in let final dynamic #t263 = #t261.[](#t262).+(self::getNum()) in let final dynamic #t264 = #t261.[]=(#t262, #t263) in #t263;
+  dynamic v10 = let final dynamic #t265 = t in let final dynamic #t266 = "x" in let final dynamic #t267 = #t265.[](#t266).+(1) in let final dynamic #t268 = #t265.[]=(#t266, #t267) in #t267;
+  dynamic v11 = let final dynamic #t269 = t in let final dynamic #t270 = "x" in let final dynamic #t271 = #t269.[](#t270) in let final dynamic #t272 = #t269.[]=(#t270, #t271.+(1)) in #t271;
+}
+static method test8(self::Test<core::double, core::num> t) → void {
+  dynamic v1 = let final dynamic #t273 = t in let final dynamic #t274 = "x" in let final dynamic #t275 = self::getInt() in let final dynamic #t276 = #t273.[]=(#t274, #t275) in #t275;
+  dynamic v2 = let final dynamic #t277 = t in let final dynamic #t278 = "x" in let final dynamic #t279 = self::getNum() in let final dynamic #t280 = #t277.[]=(#t278, #t279) in #t279;
+  dynamic v3 = let final dynamic #t281 = t in let final dynamic #t282 = "x" in let final dynamic #t283 = self::getDouble() in let final dynamic #t284 = #t281.[]=(#t282, #t283) in #t283;
+  dynamic v4 = let final dynamic #t285 = t in let final dynamic #t286 = "x" in let final dynamic #t287 = #t285.[](#t286) in #t287.==(null) ? let final dynamic #t288 = self::getInt() in let final dynamic #t289 = #t285.[]=(#t286, #t288) in #t288 : #t287;
+  dynamic v5 = let final dynamic #t290 = t in let final dynamic #t291 = "x" in let final dynamic #t292 = #t290.[](#t291) in #t292.==(null) ? let final dynamic #t293 = self::getNum() in let final dynamic #t294 = #t290.[]=(#t291, #t293) in #t293 : #t292;
+  dynamic v6 = let final dynamic #t295 = t in let final dynamic #t296 = "x" in let final dynamic #t297 = #t295.[](#t296) in #t297.==(null) ? let final dynamic #t298 = self::getDouble() in let final dynamic #t299 = #t295.[]=(#t296, #t298) in #t298 : #t297;
+  dynamic v7 = let final dynamic #t300 = t in let final dynamic #t301 = "x" in let final dynamic #t302 = #t300.[](#t301).+(self::getInt()) in let final dynamic #t303 = #t300.[]=(#t301, #t302) in #t302;
+  dynamic v8 = let final dynamic #t304 = t in let final dynamic #t305 = "x" in let final dynamic #t306 = #t304.[](#t305).+(self::getNum()) in let final dynamic #t307 = #t304.[]=(#t305, #t306) in #t306;
+  dynamic v9 = let final dynamic #t308 = t in let final dynamic #t309 = "x" in let final dynamic #t310 = #t308.[](#t309).+(self::getDouble()) in let final dynamic #t311 = #t308.[]=(#t309, #t310) in #t310;
+  dynamic v10 = let final dynamic #t312 = t in let final dynamic #t313 = "x" in let final dynamic #t314 = #t312.[](#t313).+(1) in let final dynamic #t315 = #t312.[]=(#t313, #t314) in #t314;
+  dynamic v11 = let final dynamic #t316 = t in let final dynamic #t317 = "x" in let final dynamic #t318 = #t316.[](#t317) in let final dynamic #t319 = #t316.[]=(#t317, #t318.+(1)) in #t318;
+}
+static method test9(self::Test<core::double, core::double> t) → void {
+  dynamic v2 = let final dynamic #t320 = t in let final dynamic #t321 = "x" in let final dynamic #t322 = self::getNum() in let final dynamic #t323 = #t320.[]=(#t321, #t322) in #t322;
+  dynamic v3 = let final dynamic #t324 = t in let final dynamic #t325 = "x" in let final dynamic #t326 = self::getDouble() in let final dynamic #t327 = #t324.[]=(#t325, #t326) in #t326;
+  dynamic v5 = let final dynamic #t328 = t in let final dynamic #t329 = "x" in let final dynamic #t330 = #t328.[](#t329) in #t330.==(null) ? let final dynamic #t331 = self::getNum() in let final dynamic #t332 = #t328.[]=(#t329, #t331) in #t331 : #t330;
+  dynamic v6 = let final dynamic #t333 = t in let final dynamic #t334 = "x" in let final dynamic #t335 = #t333.[](#t334) in #t335.==(null) ? let final dynamic #t336 = self::getDouble() in let final dynamic #t337 = #t333.[]=(#t334, #t336) in #t336 : #t335;
+  dynamic v7 = let final dynamic #t338 = t in let final dynamic #t339 = "x" in let final dynamic #t340 = #t338.[](#t339).+(self::getInt()) in let final dynamic #t341 = #t338.[]=(#t339, #t340) in #t340;
+  dynamic v8 = let final dynamic #t342 = t in let final dynamic #t343 = "x" in let final dynamic #t344 = #t342.[](#t343).+(self::getNum()) in let final dynamic #t345 = #t342.[]=(#t343, #t344) in #t344;
+  dynamic v9 = let final dynamic #t346 = t in let final dynamic #t347 = "x" in let final dynamic #t348 = #t346.[](#t347).+(self::getDouble()) in let final dynamic #t349 = #t346.[]=(#t347, #t348) in #t348;
+  dynamic v10 = let final dynamic #t350 = t in let final dynamic #t351 = "x" in let final dynamic #t352 = #t350.[](#t351).+(1) in let final dynamic #t353 = #t350.[]=(#t351, #t352) in #t352;
+  dynamic v11 = let final dynamic #t354 = t in let final dynamic #t355 = "x" in let final dynamic #t356 = #t354.[](#t355) in let final dynamic #t357 = #t354.[]=(#t355, #t356.+(1)) in #t356;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.direct.transformed.expect
new file mode 100644
index 0000000..eec4890
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.direct.transformed.expect
@@ -0,0 +1,47 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  self::B local;
+  local = self::f<dynamic>();
+  local.==(null) ? local = self::f<dynamic>() : null;
+  local = local.+(self::f<dynamic>());
+  local = local.*(self::f<dynamic>());
+  local = local.&(self::f<dynamic>());
+  local = local.-(1);
+  local = local.-(1);
+  dynamic v1 = local = self::f<dynamic>();
+  dynamic v2 = let final dynamic #t1 = local in #t1.==(null) ? local = self::f<dynamic>() : #t1;
+  dynamic v3 = local = local.+(self::f<dynamic>());
+  dynamic v4 = local = local.*(self::f<dynamic>());
+  dynamic v5 = local = local.&(self::f<dynamic>());
+  dynamic v6 = local = local.-(1);
+  dynamic v7 = let final dynamic #t2 = local in let final dynamic #t3 = local = #t2.-(1) in #t2;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.transformed.expect
new file mode 100644
index 0000000..1758b80
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local.dart.strong.transformed.expect
@@ -0,0 +1,47 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  self::B local;
+  local = self::f<self::B>();
+  local.{core::Object::==}(null) ?{self::B} local = self::f<self::B>() : null;
+  local = local.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+  local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  local = local.{self::B::-}(1);
+  local = local.{self::B::-}(1);
+  self::B v1 = local = self::f<self::B>();
+  self::B v2 = let final self::B #t1 = local in #t1.{core::Object::==}(null) ?{self::B} local = self::f<self::B>() : #t1;
+  self::A v3 = local = local.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+  self::B v4 = local = local.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  self::C v5 = local = local.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  self::B v6 = local = local.{self::B::-}(1);
+  self::B v7 = let final self::B #t2 = local in let final self::B #t3 = local = #t2.{self::B::-}(1) in #t2;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..4b844cb
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.direct.transformed.expect
@@ -0,0 +1,45 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method test1(core::int t) → void {
+  dynamic v1 = t = self::getInt();
+  dynamic v2 = t = self::getNum();
+  dynamic v4 = let final dynamic #t1 = t in #t1.==(null) ? t = self::getInt() : #t1;
+  dynamic v5 = let final dynamic #t2 = t in #t2.==(null) ? t = self::getNum() : #t2;
+  dynamic v7 = t = t.+(self::getInt());
+  dynamic v8 = t = t.+(self::getNum());
+  dynamic v10 = t = t.+(1);
+  dynamic v11 = let final dynamic #t3 = t in let final dynamic #t4 = t = #t3.+(1) in #t3;
+}
+static method test2(core::num t) → void {
+  dynamic v1 = t = self::getInt();
+  dynamic v2 = t = self::getNum();
+  dynamic v3 = t = self::getDouble();
+  dynamic v4 = let final dynamic #t5 = t in #t5.==(null) ? t = self::getInt() : #t5;
+  dynamic v5 = let final dynamic #t6 = t in #t6.==(null) ? t = self::getNum() : #t6;
+  dynamic v6 = let final dynamic #t7 = t in #t7.==(null) ? t = self::getDouble() : #t7;
+  dynamic v7 = t = t.+(self::getInt());
+  dynamic v8 = t = t.+(self::getNum());
+  dynamic v9 = t = t.+(self::getDouble());
+  dynamic v10 = t = t.+(1);
+  dynamic v11 = let final dynamic #t8 = t in let final dynamic #t9 = t = #t8.+(1) in #t8;
+}
+static method test3(core::double t) → void {
+  dynamic v2 = t = self::getNum();
+  dynamic v3 = t = self::getDouble();
+  dynamic v5 = let final dynamic #t10 = t in #t10.==(null) ? t = self::getNum() : #t10;
+  dynamic v6 = let final dynamic #t11 = t in #t11.==(null) ? t = self::getDouble() : #t11;
+  dynamic v7 = t = t.+(self::getInt());
+  dynamic v8 = t = t.+(self::getNum());
+  dynamic v9 = t = t.+(self::getDouble());
+  dynamic v10 = t = t.+(1);
+  dynamic v11 = let final dynamic #t12 = t in let final dynamic #t13 = t = #t12.+(1) in #t12;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..d32aa54
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_local_upwards.dart.strong.transformed.expect
@@ -0,0 +1,45 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method test1(core::int t) → void {
+  core::int v1 = t = self::getInt();
+  core::num v2 = t = self::getNum() as{TypeError} core::int;
+  core::int v4 = let final core::int #t1 = t in #t1.{core::num::==}(null) ?{core::int} t = self::getInt() : #t1;
+  core::num v5 = let final core::int #t2 = t in #t2.{core::num::==}(null) ?{core::num} t = self::getNum() as{TypeError} core::int : #t2;
+  core::int v7 = t = t.{core::num::+}(self::getInt());
+  core::num v8 = t = t.{core::num::+}(self::getNum()) as{TypeError} core::int;
+  core::int v10 = t = t.{core::num::+}(1);
+  core::int v11 = let final core::int #t3 = t in let final core::int #t4 = t = #t3.{core::num::+}(1) in #t3;
+}
+static method test2(core::num t) → void {
+  core::int v1 = t = self::getInt();
+  core::num v2 = t = self::getNum();
+  core::double v3 = t = self::getDouble();
+  core::num v4 = let final core::num #t5 = t in #t5.{core::num::==}(null) ?{core::num} t = self::getInt() : #t5;
+  core::num v5 = let final core::num #t6 = t in #t6.{core::num::==}(null) ?{core::num} t = self::getNum() : #t6;
+  core::num v6 = let final core::num #t7 = t in #t7.{core::num::==}(null) ?{core::num} t = self::getDouble() : #t7;
+  core::num v7 = t = t.{core::num::+}(self::getInt());
+  core::num v8 = t = t.{core::num::+}(self::getNum());
+  core::num v9 = t = t.{core::num::+}(self::getDouble());
+  core::num v10 = t = t.{core::num::+}(1);
+  core::num v11 = let final core::num #t8 = t in let final core::num #t9 = t = #t8.{core::num::+}(1) in #t8;
+}
+static method test3(core::double t) → void {
+  core::num v2 = t = self::getNum() as{TypeError} core::double;
+  core::double v3 = t = self::getDouble();
+  core::num v5 = let final core::double #t10 = t in #t10.{core::num::==}(null) ?{core::num} t = self::getNum() as{TypeError} core::double : #t10;
+  core::double v6 = let final core::double #t11 = t in #t11.{core::num::==}(null) ?{core::double} t = self::getDouble() : #t11;
+  core::double v7 = t = t.{core::double::+}(self::getInt());
+  core::double v8 = t = t.{core::double::+}(self::getNum());
+  core::double v9 = t = t.{core::double::+}(self::getDouble());
+  core::double v10 = t = t.{core::double::+}(1);
+  core::double v11 = let final core::double #t12 = t in let final core::double #t13 = t = #t12.{core::double::+}(1) in #t12;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.direct.transformed.expect
new file mode 100644
index 0000000..b065aea
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic v_assign = new self::A::•().f = 1;
+static field dynamic v_plus = let final dynamic #t1 = new self::A::•() in #t1.f = #t1.f.+(1);
+static field dynamic v_minus = let final dynamic #t2 = new self::A::•() in #t2.f = #t2.f.-(1);
+static field dynamic v_multiply = let final dynamic #t3 = new self::A::•() in #t3.f = #t3.f.*(1);
+static field dynamic v_prefix_pp = let final dynamic #t4 = new self::A::•() in #t4.f = #t4.f.+(1);
+static field dynamic v_prefix_mm = let final dynamic #t5 = new self::A::•() in #t5.f = #t5.f.-(1);
+static field dynamic v_postfix_pp = let final dynamic #t6 = new self::A::•() in let final dynamic #t7 = #t6.f in let final dynamic #t8 = #t6.f = #t7.+(1) in #t7;
+static field dynamic v_postfix_mm = let final dynamic #t9 = new self::A::•() in let final dynamic #t10 = #t9.f in let final dynamic #t11 = #t9.f = #t10.-(1) in #t10;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.strong.transformed.expect
new file mode 100644
index 0000000..9b1a01f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::int v_assign = new self::A::•().{self::A::f} = 1;
+static field core::int v_plus = let final self::A #t1 = new self::A::•() in #t1.{self::A::f} = #t1.{self::A::f}.{core::num::+}(1);
+static field core::int v_minus = let final self::A #t2 = new self::A::•() in #t2.{self::A::f} = #t2.{self::A::f}.{core::num::-}(1);
+static field core::int v_multiply = let final self::A #t3 = new self::A::•() in #t3.{self::A::f} = #t3.{self::A::f}.{core::num::*}(1);
+static field core::int v_prefix_pp = let final self::A #t4 = new self::A::•() in #t4.{self::A::f} = #t4.{self::A::f}.{core::num::+}(1);
+static field core::int v_prefix_mm = let final self::A #t5 = new self::A::•() in #t5.{self::A::f} = #t5.{self::A::f}.{core::num::-}(1);
+static field core::int v_postfix_pp = let final self::A #t6 = new self::A::•() in let final core::int #t7 = #t6.{self::A::f} in let final core::int #t8 = #t6.{self::A::f} = #t7.{core::num::+}(1) in #t7;
+static field core::int v_postfix_mm = let final self::A #t9 = new self::A::•() in let final core::int #t10 = #t9.{self::A::f} in let final core::int #t11 = #t9.{self::A::f} = #t10.{core::num::-}(1) in #t10;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.direct.transformed.expect
new file mode 100644
index 0000000..45017e8
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → core::int
+    return 1;
+  operator -(dynamic other) → core::double
+    return 2.0;
+}
+class B extends core::Object {
+  field self::A a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic v_prefix_pp = let final dynamic #t1 = new self::B::•() in #t1.a = #t1.a.+(1);
+static field dynamic v_prefix_mm = let final dynamic #t2 = new self::B::•() in #t2.a = #t2.a.-(1);
+static field dynamic v_postfix_pp = let final dynamic #t3 = new self::B::•() in let final dynamic #t4 = #t3.a in let final dynamic #t5 = #t3.a = #t4.+(1) in #t4;
+static field dynamic v_postfix_mm = let final dynamic #t6 = new self::B::•() in let final dynamic #t7 = #t6.a in let final dynamic #t8 = #t6.a = #t7.-(1) in #t7;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.transformed.expect
new file mode 100644
index 0000000..0f3475e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → core::int
+    return 1;
+  operator -(dynamic other) → core::double
+    return 2.0;
+}
+class B extends core::Object {
+  field self::A a = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::int v_prefix_pp = let final self::B #t1 = new self::B::•() in #t1.{self::B::a} = let final core::int #t2 = #t1.{self::B::a}.{self::A::+}(1) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:17:37: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'test::A'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A'.
+var /*@topType=int*/ v_prefix_pp = (++new B(). /*@target=B::a*/ a);
+                                    ^";
+static field core::double v_prefix_mm = let final self::B #t3 = new self::B::•() in #t3.{self::B::a} = let final core::double #t4 = #t3.{self::B::a}.{self::A::-}(1) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:18:40: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'test::A'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A'.
+var /*@topType=double*/ v_prefix_mm = (--new B(). /*@target=B::a*/ a);
+                                       ^";
+static field self::A v_postfix_pp = let final self::B #t5 = new self::B::•() in let final self::A #t6 = #t5.{self::B::a} in let final core::int #t7 = #t5.{self::B::a} = let final core::int #t8 = #t6.{self::A::+}(1) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:19:63: Error: A value of type 'dart.core::int' can't be assigned to a variable of type 'test::A'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A'.
+var /*@topType=A*/ v_postfix_pp = (new B(). /*@target=B::a*/ a++);
+                                                              ^" in #t6;
+static field self::A v_postfix_mm = let final self::B #t9 = new self::B::•() in let final self::A #t10 = #t9.{self::B::a} in let final core::double #t11 = #t9.{self::B::a} = let final core::double #t12 = #t10.{self::A::-}(1) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/infer_assign_to_property_custom.dart:20:63: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'test::A'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::A'.
+var /*@topType=A*/ v_postfix_mm = (new B(). /*@target=B::a*/ a--);
+                                                              ^" in #t10;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.direct.transformed.expect
new file mode 100644
index 0000000..cf78a86
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.direct.transformed.expect
@@ -0,0 +1,52 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test t) → void {
+    t.member = self::f<dynamic>();
+    let final dynamic #t1 = t in #t1.member.==(null) ? #t1.member = self::f<dynamic>() : null;
+    let final dynamic #t2 = t in #t2.member = #t2.member.+(self::f<dynamic>());
+    let final dynamic #t3 = t in #t3.member = #t3.member.*(self::f<dynamic>());
+    let final dynamic #t4 = t in #t4.member = #t4.member.&(self::f<dynamic>());
+    let final dynamic #t5 = t in #t5.member = #t5.member.-(1);
+    let final dynamic #t6 = t in #t6.member = #t6.member.-(1);
+    dynamic v1 = t.member = self::f<dynamic>();
+    dynamic v2 = let final dynamic #t7 = t in let final dynamic #t8 = #t7.member in #t8.==(null) ? #t7.member = self::f<dynamic>() : #t8;
+    dynamic v3 = let final dynamic #t9 = t in #t9.member = #t9.member.+(self::f<dynamic>());
+    dynamic v4 = let final dynamic #t10 = t in #t10.member = #t10.member.*(self::f<dynamic>());
+    dynamic v5 = let final dynamic #t11 = t in #t11.member = #t11.member.&(self::f<dynamic>());
+    dynamic v6 = let final dynamic #t12 = t in #t12.member = #t12.member.-(1);
+    dynamic v7 = let final dynamic #t13 = t in let final dynamic #t14 = #t13.member in let final dynamic #t15 = #t13.member = #t14.-(1) in #t14;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.transformed.expect
new file mode 100644
index 0000000..0009111
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_full.dart.strong.transformed.expect
@@ -0,0 +1,52 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test t) → void {
+    t.{self::Test::member} = self::f<self::B>();
+    let final self::Test #t1 = t in #t1.{self::Test::member}.{core::Object::==}(null) ?{self::B} #t1.{self::Test::member} = self::f<self::B>() : null;
+    let final self::Test #t2 = t in #t2.{self::Test::member} = #t2.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    let final self::Test #t3 = t in #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    let final self::Test #t4 = t in #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    let final self::Test #t5 = t in #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::-}(1);
+    let final self::Test #t6 = t in #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
+    self::B v1 = t.{self::Test::member} = self::f<self::B>();
+    self::B v2 = let final self::Test #t7 = t in let final self::B #t8 = #t7.{self::Test::member} in #t8.{core::Object::==}(null) ?{self::B} #t7.{self::Test::member} = self::f<self::B>() : #t8;
+    self::A v3 = let final self::Test #t9 = t in #t9.{self::Test::member} = #t9.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    self::B v4 = let final self::Test #t10 = t in #t10.{self::Test::member} = #t10.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    self::C v5 = let final self::Test #t11 = t in #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    self::B v6 = let final self::Test #t12 = t in #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::-}(1);
+    self::B v7 = let final self::Test #t13 = t in let final self::B #t14 = #t13.{self::Test::member} in let final self::B #t15 = #t13.{self::Test::member} = #t14.{self::B::-}(1) in #t14;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.direct.transformed.expect
new file mode 100644
index 0000000..9e6a640
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.direct.transformed.expect
@@ -0,0 +1,52 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test t) → void {
+    let final dynamic #t1 = t in #t1.==(null) ? null : #t1.member = self::f<dynamic>();
+    let final dynamic #t2 = t in #t2.==(null) ? null : #t2.member.==(null) ? #t2.member = self::f<dynamic>() : null;
+    let final dynamic #t3 = t in #t3.==(null) ? null : #t3.member = #t3.member.+(self::f<dynamic>());
+    let final dynamic #t4 = t in #t4.==(null) ? null : #t4.member = #t4.member.*(self::f<dynamic>());
+    let final dynamic #t5 = t in #t5.==(null) ? null : #t5.member = #t5.member.&(self::f<dynamic>());
+    let final dynamic #t6 = t in #t6.==(null) ? null : #t6.member = #t6.member.-(1);
+    let final dynamic #t7 = t in #t7.==(null) ? null : #t7.member = #t7.member.-(1);
+    dynamic v1 = let final dynamic #t8 = t in #t8.==(null) ? null : #t8.member = self::f<dynamic>();
+    dynamic v2 = let final dynamic #t9 = t in #t9.==(null) ? null : let final dynamic #t10 = #t9.member in #t10.==(null) ? #t9.member = self::f<dynamic>() : #t10;
+    dynamic v3 = let final dynamic #t11 = t in #t11.==(null) ? null : #t11.member = #t11.member.+(self::f<dynamic>());
+    dynamic v4 = let final dynamic #t12 = t in #t12.==(null) ? null : #t12.member = #t12.member.*(self::f<dynamic>());
+    dynamic v5 = let final dynamic #t13 = t in #t13.==(null) ? null : #t13.member = #t13.member.&(self::f<dynamic>());
+    dynamic v6 = let final dynamic #t14 = t in #t14.==(null) ? null : #t14.member = #t14.member.-(1);
+    dynamic v7 = let final dynamic #t15 = t in #t15.==(null) ? null : let final dynamic #t16 = #t15.member in let final dynamic #t17 = #t15.member = #t16.-(1) in #t16;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect
new file mode 100644
index 0000000..d13eac7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware.dart.strong.transformed.expect
@@ -0,0 +1,52 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Test extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test t) → void {
+    let final self::Test #t1 = t in #t1.==(null) ?{self::B} null : #t1.{self::Test::member} = self::f<self::B>();
+    let final self::Test #t2 = t in #t2.==(null) ?{self::B} null : #t2.{self::Test::member}.{core::Object::==}(null) ?{self::B} #t2.{self::Test::member} = self::f<self::B>() : null;
+    let final self::Test #t3 = t in #t3.==(null) ?{self::A} null : #t3.{self::Test::member} = #t3.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    let final self::Test #t4 = t in #t4.==(null) ?{self::B} null : #t4.{self::Test::member} = #t4.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    let final self::Test #t5 = t in #t5.==(null) ?{self::C} null : #t5.{self::Test::member} = #t5.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    let final self::Test #t6 = t in #t6.==(null) ?{self::B} null : #t6.{self::Test::member} = #t6.{self::Test::member}.{self::B::-}(1);
+    let final self::Test #t7 = t in #t7.==(null) ?{self::B} null : #t7.{self::Test::member} = #t7.{self::Test::member}.{self::B::-}(1);
+    self::B v1 = let final self::Test #t8 = t in #t8.==(null) ?{self::B} null : #t8.{self::Test::member} = self::f<self::B>();
+    self::B v2 = let final self::Test #t9 = t in #t9.==(null) ?{self::B} null : let final self::B #t10 = #t9.{self::Test::member} in #t10.{core::Object::==}(null) ?{self::B} #t9.{self::Test::member} = self::f<self::B>() : #t10;
+    self::A v3 = let final self::Test #t11 = t in #t11.==(null) ?{self::A} null : #t11.{self::Test::member} = #t11.{self::Test::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    self::B v4 = let final self::Test #t12 = t in #t12.==(null) ?{self::B} null : #t12.{self::Test::member} = #t12.{self::Test::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    self::C v5 = let final self::Test #t13 = t in #t13.==(null) ?{self::C} null : #t13.{self::Test::member} = #t13.{self::Test::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    self::B v6 = let final self::Test #t14 = t in #t14.==(null) ?{self::B} null : #t14.{self::Test::member} = #t14.{self::Test::member}.{self::B::-}(1);
+    self::B v7 = let final self::Test #t15 = t in #t15.==(null) ?{self::B} null : let final self::B #t16 = #t15.{self::Test::member} in let final self::B #t17 = #t15.{self::Test::member} = #t16.{self::B::-}(1) in #t16;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..59129cd
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.direct.transformed.expect
@@ -0,0 +1,63 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test1 t) → void {
+    dynamic v1 = let final dynamic #t1 = t in #t1.==(null) ? null : #t1.prop = self::getInt();
+    dynamic v2 = let final dynamic #t2 = t in #t2.==(null) ? null : #t2.prop = self::getNum();
+    dynamic v4 = let final dynamic #t3 = t in #t3.==(null) ? null : let final dynamic #t4 = #t3.prop in #t4.==(null) ? #t3.prop = self::getInt() : #t4;
+    dynamic v5 = let final dynamic #t5 = t in #t5.==(null) ? null : let final dynamic #t6 = #t5.prop in #t6.==(null) ? #t5.prop = self::getNum() : #t6;
+    dynamic v7 = let final dynamic #t7 = t in #t7.==(null) ? null : #t7.prop = #t7.prop.+(self::getInt());
+    dynamic v8 = let final dynamic #t8 = t in #t8.==(null) ? null : #t8.prop = #t8.prop.+(self::getNum());
+    dynamic v10 = let final dynamic #t9 = t in #t9.==(null) ? null : #t9.prop = #t9.prop.+(1);
+    dynamic v11 = let final dynamic #t10 = t in #t10.==(null) ? null : let final dynamic #t11 = #t10.prop in let final dynamic #t12 = #t10.prop = #t11.+(1) in #t11;
+  }
+}
+class Test2 extends core::Object {
+  field core::num prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test2 t) → void {
+    dynamic v1 = let final dynamic #t13 = t in #t13.==(null) ? null : #t13.prop = self::getInt();
+    dynamic v2 = let final dynamic #t14 = t in #t14.==(null) ? null : #t14.prop = self::getNum();
+    dynamic v3 = let final dynamic #t15 = t in #t15.==(null) ? null : #t15.prop = self::getDouble();
+    dynamic v4 = let final dynamic #t16 = t in #t16.==(null) ? null : let final dynamic #t17 = #t16.prop in #t17.==(null) ? #t16.prop = self::getInt() : #t17;
+    dynamic v5 = let final dynamic #t18 = t in #t18.==(null) ? null : let final dynamic #t19 = #t18.prop in #t19.==(null) ? #t18.prop = self::getNum() : #t19;
+    dynamic v6 = let final dynamic #t20 = t in #t20.==(null) ? null : let final dynamic #t21 = #t20.prop in #t21.==(null) ? #t20.prop = self::getDouble() : #t21;
+    dynamic v7 = let final dynamic #t22 = t in #t22.==(null) ? null : #t22.prop = #t22.prop.+(self::getInt());
+    dynamic v8 = let final dynamic #t23 = t in #t23.==(null) ? null : #t23.prop = #t23.prop.+(self::getNum());
+    dynamic v9 = let final dynamic #t24 = t in #t24.==(null) ? null : #t24.prop = #t24.prop.+(self::getDouble());
+    dynamic v10 = let final dynamic #t25 = t in #t25.==(null) ? null : #t25.prop = #t25.prop.+(1);
+    dynamic v11 = let final dynamic #t26 = t in #t26.==(null) ? null : let final dynamic #t27 = #t26.prop in let final dynamic #t28 = #t26.prop = #t27.+(1) in #t27;
+  }
+}
+class Test3 extends core::Object {
+  field core::double prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test3(self::Test3 t) → void {
+    dynamic v2 = let final dynamic #t29 = t in #t29.==(null) ? null : #t29.prop = self::getNum();
+    dynamic v3 = let final dynamic #t30 = t in #t30.==(null) ? null : #t30.prop = self::getDouble();
+    dynamic v5 = let final dynamic #t31 = t in #t31.==(null) ? null : let final dynamic #t32 = #t31.prop in #t32.==(null) ? #t31.prop = self::getNum() : #t32;
+    dynamic v6 = let final dynamic #t33 = t in #t33.==(null) ? null : let final dynamic #t34 = #t33.prop in #t34.==(null) ? #t33.prop = self::getDouble() : #t34;
+    dynamic v7 = let final dynamic #t35 = t in #t35.==(null) ? null : #t35.prop = #t35.prop.+(self::getInt());
+    dynamic v8 = let final dynamic #t36 = t in #t36.==(null) ? null : #t36.prop = #t36.prop.+(self::getNum());
+    dynamic v9 = let final dynamic #t37 = t in #t37.==(null) ? null : #t37.prop = #t37.prop.+(self::getDouble());
+    dynamic v10 = let final dynamic #t38 = t in #t38.==(null) ? null : #t38.prop = #t38.prop.+(1);
+    dynamic v11 = let final dynamic #t39 = t in #t39.==(null) ? null : let final dynamic #t40 = #t39.prop in let final dynamic #t41 = #t39.prop = #t40.+(1) in #t40;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..834d57b
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_null_aware_upwards.dart.strong.transformed.expect
@@ -0,0 +1,63 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test1 t) → void {
+    core::int v1 = let final self::Test1 #t1 = t in #t1.==(null) ?{core::int} null : #t1.{self::Test1::prop} = self::getInt();
+    core::num v2 = let final self::Test1 #t2 = t in #t2.==(null) ?{core::num} null : #t2.{self::Test1::prop} = self::getNum() as{TypeError} core::int;
+    core::int v4 = let final self::Test1 #t3 = t in #t3.==(null) ?{core::int} null : let final core::int #t4 = #t3.{self::Test1::prop} in #t4.{core::num::==}(null) ?{core::int} #t3.{self::Test1::prop} = self::getInt() : #t4;
+    core::num v5 = let final self::Test1 #t5 = t in #t5.==(null) ?{core::num} null : let final core::int #t6 = #t5.{self::Test1::prop} in #t6.{core::num::==}(null) ?{core::num} #t5.{self::Test1::prop} = self::getNum() as{TypeError} core::int : #t6;
+    core::int v7 = let final self::Test1 #t7 = t in #t7.==(null) ?{core::int} null : #t7.{self::Test1::prop} = #t7.{self::Test1::prop}.{core::num::+}(self::getInt());
+    core::num v8 = let final self::Test1 #t8 = t in #t8.==(null) ?{core::num} null : #t8.{self::Test1::prop} = #t8.{self::Test1::prop}.{core::num::+}(self::getNum()) as{TypeError} core::int;
+    core::int v10 = let final self::Test1 #t9 = t in #t9.==(null) ?{core::int} null : #t9.{self::Test1::prop} = #t9.{self::Test1::prop}.{core::num::+}(1);
+    core::int v11 = let final self::Test1 #t10 = t in #t10.==(null) ?{core::int} null : let final core::int #t11 = #t10.{self::Test1::prop} in let final core::int #t12 = #t10.{self::Test1::prop} = #t11.{core::num::+}(1) in #t11;
+  }
+}
+class Test2 extends core::Object {
+  field core::num prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test2 t) → void {
+    core::int v1 = let final self::Test2 #t13 = t in #t13.==(null) ?{core::int} null : #t13.{self::Test2::prop} = self::getInt();
+    core::num v2 = let final self::Test2 #t14 = t in #t14.==(null) ?{core::num} null : #t14.{self::Test2::prop} = self::getNum();
+    core::double v3 = let final self::Test2 #t15 = t in #t15.==(null) ?{core::double} null : #t15.{self::Test2::prop} = self::getDouble();
+    core::num v4 = let final self::Test2 #t16 = t in #t16.==(null) ?{core::num} null : let final core::num #t17 = #t16.{self::Test2::prop} in #t17.{core::num::==}(null) ?{core::num} #t16.{self::Test2::prop} = self::getInt() : #t17;
+    core::num v5 = let final self::Test2 #t18 = t in #t18.==(null) ?{core::num} null : let final core::num #t19 = #t18.{self::Test2::prop} in #t19.{core::num::==}(null) ?{core::num} #t18.{self::Test2::prop} = self::getNum() : #t19;
+    core::num v6 = let final self::Test2 #t20 = t in #t20.==(null) ?{core::num} null : let final core::num #t21 = #t20.{self::Test2::prop} in #t21.{core::num::==}(null) ?{core::num} #t20.{self::Test2::prop} = self::getDouble() : #t21;
+    core::num v7 = let final self::Test2 #t22 = t in #t22.==(null) ?{core::num} null : #t22.{self::Test2::prop} = #t22.{self::Test2::prop}.{core::num::+}(self::getInt());
+    core::num v8 = let final self::Test2 #t23 = t in #t23.==(null) ?{core::num} null : #t23.{self::Test2::prop} = #t23.{self::Test2::prop}.{core::num::+}(self::getNum());
+    core::num v9 = let final self::Test2 #t24 = t in #t24.==(null) ?{core::num} null : #t24.{self::Test2::prop} = #t24.{self::Test2::prop}.{core::num::+}(self::getDouble());
+    core::num v10 = let final self::Test2 #t25 = t in #t25.==(null) ?{core::num} null : #t25.{self::Test2::prop} = #t25.{self::Test2::prop}.{core::num::+}(1);
+    core::num v11 = let final self::Test2 #t26 = t in #t26.==(null) ?{core::num} null : let final core::num #t27 = #t26.{self::Test2::prop} in let final core::num #t28 = #t26.{self::Test2::prop} = #t27.{core::num::+}(1) in #t27;
+  }
+}
+class Test3 extends core::Object {
+  field core::double prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test3(self::Test3 t) → void {
+    core::num v2 = let final self::Test3 #t29 = t in #t29.==(null) ?{core::num} null : #t29.{self::Test3::prop} = self::getNum() as{TypeError} core::double;
+    core::double v3 = let final self::Test3 #t30 = t in #t30.==(null) ?{core::double} null : #t30.{self::Test3::prop} = self::getDouble();
+    core::num v5 = let final self::Test3 #t31 = t in #t31.==(null) ?{core::num} null : let final core::double #t32 = #t31.{self::Test3::prop} in #t32.{core::num::==}(null) ?{core::num} #t31.{self::Test3::prop} = self::getNum() as{TypeError} core::double : #t32;
+    core::double v6 = let final self::Test3 #t33 = t in #t33.==(null) ?{core::double} null : let final core::double #t34 = #t33.{self::Test3::prop} in #t34.{core::num::==}(null) ?{core::double} #t33.{self::Test3::prop} = self::getDouble() : #t34;
+    core::double v7 = let final self::Test3 #t35 = t in #t35.==(null) ?{core::double} null : #t35.{self::Test3::prop} = #t35.{self::Test3::prop}.{core::double::+}(self::getInt());
+    core::double v8 = let final self::Test3 #t36 = t in #t36.==(null) ?{core::double} null : #t36.{self::Test3::prop} = #t36.{self::Test3::prop}.{core::double::+}(self::getNum());
+    core::double v9 = let final self::Test3 #t37 = t in #t37.==(null) ?{core::double} null : #t37.{self::Test3::prop} = #t37.{self::Test3::prop}.{core::double::+}(self::getDouble());
+    core::double v10 = let final self::Test3 #t38 = t in #t38.==(null) ?{core::double} null : #t38.{self::Test3::prop} = #t38.{self::Test3::prop}.{core::double::+}(1);
+    core::double v11 = let final self::Test3 #t39 = t in #t39.==(null) ?{core::double} null : let final core::double #t40 = #t39.{self::Test3::prop} in let final core::double #t41 = #t39.{self::Test3::prop} = #t40.{core::double::+}(1) in #t40;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.direct.transformed.expect
new file mode 100644
index 0000000..ccc4134
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.direct.transformed.expect
@@ -0,0 +1,57 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Base extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Test extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    super.{self::Base::member} = self::f<dynamic>();
+    super.{self::Base::member}.==(null) ? super.{self::Base::member} = self::f<dynamic>() : null;
+    super.{self::Base::member} = super.{self::Base::member}.+(self::f<dynamic>());
+    super.{self::Base::member} = super.{self::Base::member}.*(self::f<dynamic>());
+    super.{self::Base::member} = super.{self::Base::member}.&(self::f<dynamic>());
+    super.{self::Base::member} = super.{self::Base::member}.-(1);
+    super.{self::Base::member} = super.{self::Base::member}.-(1);
+    dynamic v1 = super.{self::Base::member} = self::f<dynamic>();
+    dynamic v2 = let final dynamic #t1 = super.{self::Base::member} in #t1.==(null) ? super.{self::Base::member} = self::f<dynamic>() : #t1;
+    dynamic v3 = super.{self::Base::member} = super.{self::Base::member}.+(self::f<dynamic>());
+    dynamic v4 = super.{self::Base::member} = super.{self::Base::member}.*(self::f<dynamic>());
+    dynamic v5 = super.{self::Base::member} = super.{self::Base::member}.&(self::f<dynamic>());
+    dynamic v6 = super.{self::Base::member} = super.{self::Base::member}.-(1);
+    dynamic v7 = let final dynamic #t2 = super.{self::Base::member} in let final dynamic #t3 = super.{self::Base::member} = #t2.-(1) in #t2;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.transformed.expect
new file mode 100644
index 0000000..5963336
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super.dart.strong.transformed.expect
@@ -0,0 +1,57 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class Base extends core::Object {
+  field self::B member = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Test extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    super.{self::Base::member} = self::f<self::B>();
+    super.{self::Base::member}.{core::Object::==}(null) ?{self::B} super.{self::Base::member} = self::f<self::B>() : null;
+    super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
+    super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
+    self::B v1 = super.{self::Base::member} = self::f<self::B>();
+    self::B v2 = let final self::B #t1 = super.{self::Base::member} in #t1.{core::Object::==}(null) ?{self::B} super.{self::Base::member} = self::f<self::B>() : #t1;
+    self::A v3 = super.{self::Base::member} = super.{self::Base::member}.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+    self::B v4 = super.{self::Base::member} = super.{self::Base::member}.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+    self::C v5 = super.{self::Base::member} = super.{self::Base::member}.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+    self::B v6 = super.{self::Base::member} = super.{self::Base::member}.{self::B::-}(1);
+    self::B v7 = let final self::B #t2 = super.{self::Base::member} in let final self::B #t3 = super.{self::Base::member} = #t2.{self::B::-}(1) in #t2;
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..66e910a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.direct.transformed.expect
@@ -0,0 +1,68 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  field core::int intProp = null;
+  field core::num numProp = null;
+  field core::double doubleProp = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Test1 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v1 = super.{self::Base::intProp} = self::getInt();
+    dynamic v2 = super.{self::Base::intProp} = self::getNum();
+    dynamic v4 = let final dynamic #t1 = super.{self::Base::intProp} in #t1.==(null) ? super.{self::Base::intProp} = self::getInt() : #t1;
+    dynamic v5 = let final dynamic #t2 = super.{self::Base::intProp} in #t2.==(null) ? super.{self::Base::intProp} = self::getNum() : #t2;
+    dynamic v7 = super.{self::Base::intProp} = super.{self::Base::intProp}.+(self::getInt());
+    dynamic v8 = super.{self::Base::intProp} = super.{self::Base::intProp}.+(self::getNum());
+    dynamic v10 = super.{self::Base::intProp} = super.{self::Base::intProp}.+(1);
+    dynamic v11 = let final dynamic #t3 = super.{self::Base::intProp} in let final dynamic #t4 = super.{self::Base::intProp} = #t3.+(1) in #t3;
+  }
+}
+class Test2 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    dynamic v1 = super.{self::Base::numProp} = self::getInt();
+    dynamic v2 = super.{self::Base::numProp} = self::getNum();
+    dynamic v3 = super.{self::Base::numProp} = self::getDouble();
+    dynamic v4 = let final dynamic #t5 = super.{self::Base::numProp} in #t5.==(null) ? super.{self::Base::numProp} = self::getInt() : #t5;
+    dynamic v5 = let final dynamic #t6 = super.{self::Base::numProp} in #t6.==(null) ? super.{self::Base::numProp} = self::getNum() : #t6;
+    dynamic v6 = let final dynamic #t7 = super.{self::Base::numProp} in #t7.==(null) ? super.{self::Base::numProp} = self::getDouble() : #t7;
+    dynamic v7 = super.{self::Base::numProp} = super.{self::Base::numProp}.+(self::getInt());
+    dynamic v8 = super.{self::Base::numProp} = super.{self::Base::numProp}.+(self::getNum());
+    dynamic v9 = super.{self::Base::numProp} = super.{self::Base::numProp}.+(self::getDouble());
+    dynamic v10 = super.{self::Base::numProp} = super.{self::Base::numProp}.+(1);
+    dynamic v11 = let final dynamic #t8 = super.{self::Base::numProp} in let final dynamic #t9 = super.{self::Base::numProp} = #t8.+(1) in #t8;
+  }
+}
+class Test3 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test3() → void {
+    dynamic v2 = super.{self::Base::doubleProp} = self::getNum();
+    dynamic v3 = super.{self::Base::doubleProp} = self::getDouble();
+    dynamic v5 = let final dynamic #t10 = super.{self::Base::doubleProp} in #t10.==(null) ? super.{self::Base::doubleProp} = self::getNum() : #t10;
+    dynamic v6 = let final dynamic #t11 = super.{self::Base::doubleProp} in #t11.==(null) ? super.{self::Base::doubleProp} = self::getDouble() : #t11;
+    dynamic v7 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.+(self::getInt());
+    dynamic v8 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.+(self::getNum());
+    dynamic v9 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.+(self::getDouble());
+    dynamic v10 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.+(1);
+    dynamic v11 = let final dynamic #t12 = super.{self::Base::doubleProp} in let final dynamic #t13 = super.{self::Base::doubleProp} = #t12.+(1) in #t12;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..73e1212
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_super_upwards.dart.strong.transformed.expect
@@ -0,0 +1,68 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  field core::int intProp = null;
+  field core::num numProp = null;
+  field core::double doubleProp = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Test1 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    core::int v1 = super.{self::Base::intProp} = self::getInt();
+    core::num v2 = super.{self::Base::intProp} = self::getNum() as{TypeError} core::int;
+    core::int v4 = let final core::int #t1 = super.{self::Base::intProp} in #t1.{core::num::==}(null) ?{core::int} super.{self::Base::intProp} = self::getInt() : #t1;
+    core::num v5 = let final core::int #t2 = super.{self::Base::intProp} in #t2.{core::num::==}(null) ?{core::num} super.{self::Base::intProp} = self::getNum() as{TypeError} core::int : #t2;
+    core::int v7 = super.{self::Base::intProp} = super.{self::Base::intProp}.{core::num::+}(self::getInt());
+    core::num v8 = super.{self::Base::intProp} = super.{self::Base::intProp}.{core::num::+}(self::getNum()) as{TypeError} core::int;
+    core::int v10 = super.{self::Base::intProp} = super.{self::Base::intProp}.{core::num::+}(1);
+    core::int v11 = let final core::int #t3 = super.{self::Base::intProp} in let final core::int #t4 = super.{self::Base::intProp} = #t3.{core::num::+}(1) in #t3;
+  }
+}
+class Test2 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test() → void {
+    core::int v1 = super.{self::Base::numProp} = self::getInt();
+    core::num v2 = super.{self::Base::numProp} = self::getNum();
+    core::double v3 = super.{self::Base::numProp} = self::getDouble();
+    core::num v4 = let final core::num #t5 = super.{self::Base::numProp} in #t5.{core::num::==}(null) ?{core::num} super.{self::Base::numProp} = self::getInt() : #t5;
+    core::num v5 = let final core::num #t6 = super.{self::Base::numProp} in #t6.{core::num::==}(null) ?{core::num} super.{self::Base::numProp} = self::getNum() : #t6;
+    core::num v6 = let final core::num #t7 = super.{self::Base::numProp} in #t7.{core::num::==}(null) ?{core::num} super.{self::Base::numProp} = self::getDouble() : #t7;
+    core::num v7 = super.{self::Base::numProp} = super.{self::Base::numProp}.{core::num::+}(self::getInt());
+    core::num v8 = super.{self::Base::numProp} = super.{self::Base::numProp}.{core::num::+}(self::getNum());
+    core::num v9 = super.{self::Base::numProp} = super.{self::Base::numProp}.{core::num::+}(self::getDouble());
+    core::num v10 = super.{self::Base::numProp} = super.{self::Base::numProp}.{core::num::+}(1);
+    core::num v11 = let final core::num #t8 = super.{self::Base::numProp} in let final core::num #t9 = super.{self::Base::numProp} = #t8.{core::num::+}(1) in #t8;
+  }
+}
+class Test3 extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method test3() → void {
+    core::num v2 = super.{self::Base::doubleProp} = self::getNum() as{TypeError} core::double;
+    core::double v3 = super.{self::Base::doubleProp} = self::getDouble();
+    core::num v5 = let final core::double #t10 = super.{self::Base::doubleProp} in #t10.{core::num::==}(null) ?{core::num} super.{self::Base::doubleProp} = self::getNum() as{TypeError} core::double : #t10;
+    core::double v6 = let final core::double #t11 = super.{self::Base::doubleProp} in #t11.{core::num::==}(null) ?{core::double} super.{self::Base::doubleProp} = self::getDouble() : #t11;
+    core::double v7 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.{core::double::+}(self::getInt());
+    core::double v8 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.{core::double::+}(self::getNum());
+    core::double v9 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.{core::double::+}(self::getDouble());
+    core::double v10 = super.{self::Base::doubleProp} = super.{self::Base::doubleProp}.{core::double::+}(1);
+    core::double v11 = let final core::double #t12 = super.{self::Base::doubleProp} in let final core::double #t13 = super.{self::Base::doubleProp} = #t12.{core::double::+}(1) in #t12;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..d268f79
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.direct.transformed.expect
@@ -0,0 +1,63 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test1 t) → void {
+    dynamic v1 = t.prop = self::getInt();
+    dynamic v2 = t.prop = self::getNum();
+    dynamic v4 = let final dynamic #t1 = t in let final dynamic #t2 = #t1.prop in #t2.==(null) ? #t1.prop = self::getInt() : #t2;
+    dynamic v5 = let final dynamic #t3 = t in let final dynamic #t4 = #t3.prop in #t4.==(null) ? #t3.prop = self::getNum() : #t4;
+    dynamic v7 = let final dynamic #t5 = t in #t5.prop = #t5.prop.+(self::getInt());
+    dynamic v8 = let final dynamic #t6 = t in #t6.prop = #t6.prop.+(self::getNum());
+    dynamic v10 = let final dynamic #t7 = t in #t7.prop = #t7.prop.+(1);
+    dynamic v11 = let final dynamic #t8 = t in let final dynamic #t9 = #t8.prop in let final dynamic #t10 = #t8.prop = #t9.+(1) in #t9;
+  }
+}
+class Test2 extends core::Object {
+  field core::num prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test2 t) → void {
+    dynamic v1 = t.prop = self::getInt();
+    dynamic v2 = t.prop = self::getNum();
+    dynamic v3 = t.prop = self::getDouble();
+    dynamic v4 = let final dynamic #t11 = t in let final dynamic #t12 = #t11.prop in #t12.==(null) ? #t11.prop = self::getInt() : #t12;
+    dynamic v5 = let final dynamic #t13 = t in let final dynamic #t14 = #t13.prop in #t14.==(null) ? #t13.prop = self::getNum() : #t14;
+    dynamic v6 = let final dynamic #t15 = t in let final dynamic #t16 = #t15.prop in #t16.==(null) ? #t15.prop = self::getDouble() : #t16;
+    dynamic v7 = let final dynamic #t17 = t in #t17.prop = #t17.prop.+(self::getInt());
+    dynamic v8 = let final dynamic #t18 = t in #t18.prop = #t18.prop.+(self::getNum());
+    dynamic v9 = let final dynamic #t19 = t in #t19.prop = #t19.prop.+(self::getDouble());
+    dynamic v10 = let final dynamic #t20 = t in #t20.prop = #t20.prop.+(1);
+    dynamic v11 = let final dynamic #t21 = t in let final dynamic #t22 = #t21.prop in let final dynamic #t23 = #t21.prop = #t22.+(1) in #t22;
+  }
+}
+class Test3 extends core::Object {
+  field core::double prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test3(self::Test3 t) → void {
+    dynamic v2 = t.prop = self::getNum();
+    dynamic v3 = t.prop = self::getDouble();
+    dynamic v5 = let final dynamic #t24 = t in let final dynamic #t25 = #t24.prop in #t25.==(null) ? #t24.prop = self::getNum() : #t25;
+    dynamic v6 = let final dynamic #t26 = t in let final dynamic #t27 = #t26.prop in #t27.==(null) ? #t26.prop = self::getDouble() : #t27;
+    dynamic v7 = let final dynamic #t28 = t in #t28.prop = #t28.prop.+(self::getInt());
+    dynamic v8 = let final dynamic #t29 = t in #t29.prop = #t29.prop.+(self::getNum());
+    dynamic v9 = let final dynamic #t30 = t in #t30.prop = #t30.prop.+(self::getDouble());
+    dynamic v10 = let final dynamic #t31 = t in #t31.prop = #t31.prop.+(1);
+    dynamic v11 = let final dynamic #t32 = t in let final dynamic #t33 = #t32.prop in let final dynamic #t34 = #t32.prop = #t33.+(1) in #t33;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..78c30db
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_property_upwards.dart.strong.transformed.expect
@@ -0,0 +1,63 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Test1 extends core::Object {
+  field core::int prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test1 t) → void {
+    core::int v1 = t.{self::Test1::prop} = self::getInt();
+    core::num v2 = t.{self::Test1::prop} = self::getNum() as{TypeError} core::int;
+    core::int v4 = let final self::Test1 #t1 = t in let final core::int #t2 = #t1.{self::Test1::prop} in #t2.{core::num::==}(null) ?{core::int} #t1.{self::Test1::prop} = self::getInt() : #t2;
+    core::num v5 = let final self::Test1 #t3 = t in let final core::int #t4 = #t3.{self::Test1::prop} in #t4.{core::num::==}(null) ?{core::num} #t3.{self::Test1::prop} = self::getNum() as{TypeError} core::int : #t4;
+    core::int v7 = let final self::Test1 #t5 = t in #t5.{self::Test1::prop} = #t5.{self::Test1::prop}.{core::num::+}(self::getInt());
+    core::num v8 = let final self::Test1 #t6 = t in #t6.{self::Test1::prop} = #t6.{self::Test1::prop}.{core::num::+}(self::getNum()) as{TypeError} core::int;
+    core::int v10 = let final self::Test1 #t7 = t in #t7.{self::Test1::prop} = #t7.{self::Test1::prop}.{core::num::+}(1);
+    core::int v11 = let final self::Test1 #t8 = t in let final core::int #t9 = #t8.{self::Test1::prop} in let final core::int #t10 = #t8.{self::Test1::prop} = #t9.{core::num::+}(1) in #t9;
+  }
+}
+class Test2 extends core::Object {
+  field core::num prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test(self::Test2 t) → void {
+    core::int v1 = t.{self::Test2::prop} = self::getInt();
+    core::num v2 = t.{self::Test2::prop} = self::getNum();
+    core::double v3 = t.{self::Test2::prop} = self::getDouble();
+    core::num v4 = let final self::Test2 #t11 = t in let final core::num #t12 = #t11.{self::Test2::prop} in #t12.{core::num::==}(null) ?{core::num} #t11.{self::Test2::prop} = self::getInt() : #t12;
+    core::num v5 = let final self::Test2 #t13 = t in let final core::num #t14 = #t13.{self::Test2::prop} in #t14.{core::num::==}(null) ?{core::num} #t13.{self::Test2::prop} = self::getNum() : #t14;
+    core::num v6 = let final self::Test2 #t15 = t in let final core::num #t16 = #t15.{self::Test2::prop} in #t16.{core::num::==}(null) ?{core::num} #t15.{self::Test2::prop} = self::getDouble() : #t16;
+    core::num v7 = let final self::Test2 #t17 = t in #t17.{self::Test2::prop} = #t17.{self::Test2::prop}.{core::num::+}(self::getInt());
+    core::num v8 = let final self::Test2 #t18 = t in #t18.{self::Test2::prop} = #t18.{self::Test2::prop}.{core::num::+}(self::getNum());
+    core::num v9 = let final self::Test2 #t19 = t in #t19.{self::Test2::prop} = #t19.{self::Test2::prop}.{core::num::+}(self::getDouble());
+    core::num v10 = let final self::Test2 #t20 = t in #t20.{self::Test2::prop} = #t20.{self::Test2::prop}.{core::num::+}(1);
+    core::num v11 = let final self::Test2 #t21 = t in let final core::num #t22 = #t21.{self::Test2::prop} in let final core::num #t23 = #t21.{self::Test2::prop} = #t22.{core::num::+}(1) in #t22;
+  }
+}
+class Test3 extends core::Object {
+  field core::double prop = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method test3(self::Test3 t) → void {
+    core::num v2 = t.{self::Test3::prop} = self::getNum() as{TypeError} core::double;
+    core::double v3 = t.{self::Test3::prop} = self::getDouble();
+    core::num v5 = let final self::Test3 #t24 = t in let final core::double #t25 = #t24.{self::Test3::prop} in #t25.{core::num::==}(null) ?{core::num} #t24.{self::Test3::prop} = self::getNum() as{TypeError} core::double : #t25;
+    core::double v6 = let final self::Test3 #t26 = t in let final core::double #t27 = #t26.{self::Test3::prop} in #t27.{core::num::==}(null) ?{core::double} #t26.{self::Test3::prop} = self::getDouble() : #t27;
+    core::double v7 = let final self::Test3 #t28 = t in #t28.{self::Test3::prop} = #t28.{self::Test3::prop}.{core::double::+}(self::getInt());
+    core::double v8 = let final self::Test3 #t29 = t in #t29.{self::Test3::prop} = #t29.{self::Test3::prop}.{core::double::+}(self::getNum());
+    core::double v9 = let final self::Test3 #t30 = t in #t30.{self::Test3::prop} = #t30.{self::Test3::prop}.{core::double::+}(self::getDouble());
+    core::double v10 = let final self::Test3 #t31 = t in #t31.{self::Test3::prop} = #t31.{self::Test3::prop}.{core::double::+}(1);
+    core::double v11 = let final self::Test3 #t32 = t in let final core::double #t33 = #t32.{self::Test3::prop} in let final core::double #t34 = #t32.{self::Test3::prop} = #t33.{core::double::+}(1) in #t33;
+  }
+}
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.direct.transformed.expect
new file mode 100644
index 0000000..5d4e0bc7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A a = new self::A::•();
+static field dynamic b = self::a.f = 1;
+static field dynamic c = 0;
+static field dynamic d = self::c = 1;
+static method main() → dynamic {
+  self::a;
+  self::b;
+  self::c;
+  self::d;
+}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.strong.transformed.expect
new file mode 100644
index 0000000..2fe641f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_ref.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A a = new self::A::•();
+static field core::int b = self::a.{self::A::f} = 1;
+static field core::int c = 0;
+static field core::int d = self::c = 1;
+static method main() → dynamic {
+  self::a;
+  self::b;
+  self::c;
+  self::d;
+}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.direct.transformed.expect
new file mode 100644
index 0000000..fa2ea61
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.direct.transformed.expect
@@ -0,0 +1,64 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  static field self::B staticVariable = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static field self::B topLevelVariable;
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test_topLevelVariable() → void {
+  self::topLevelVariable = self::f<dynamic>();
+  self::topLevelVariable.==(null) ? self::topLevelVariable = self::f<dynamic>() : null;
+  self::topLevelVariable = self::topLevelVariable.+(self::f<dynamic>());
+  self::topLevelVariable = self::topLevelVariable.*(self::f<dynamic>());
+  self::topLevelVariable = self::topLevelVariable.&(self::f<dynamic>());
+  self::topLevelVariable = self::topLevelVariable.-(1);
+  self::topLevelVariable = self::topLevelVariable.-(1);
+  dynamic v1 = self::topLevelVariable = self::f<dynamic>();
+  dynamic v2 = let final dynamic #t1 = self::topLevelVariable in #t1.==(null) ? self::topLevelVariable = self::f<dynamic>() : #t1;
+  dynamic v3 = self::topLevelVariable = self::topLevelVariable.+(self::f<dynamic>());
+  dynamic v4 = self::topLevelVariable = self::topLevelVariable.*(self::f<dynamic>());
+  dynamic v5 = self::topLevelVariable = self::topLevelVariable.&(self::f<dynamic>());
+  dynamic v6 = self::topLevelVariable = self::topLevelVariable.-(1);
+  dynamic v7 = let final dynamic #t2 = self::topLevelVariable in let final dynamic #t3 = self::topLevelVariable = #t2.-(1) in #t2;
+}
+static method test_staticVariable() → void {
+  self::B::staticVariable = self::f<dynamic>();
+  self::B::staticVariable.==(null) ? self::B::staticVariable = self::f<dynamic>() : null;
+  self::B::staticVariable = self::B::staticVariable.+(self::f<dynamic>());
+  self::B::staticVariable = self::B::staticVariable.*(self::f<dynamic>());
+  self::B::staticVariable = self::B::staticVariable.&(self::f<dynamic>());
+  self::B::staticVariable = self::B::staticVariable.-(1);
+  self::B::staticVariable = self::B::staticVariable.-(1);
+  dynamic v1 = self::B::staticVariable = self::f<dynamic>();
+  dynamic v2 = let final dynamic #t4 = self::B::staticVariable in #t4.==(null) ? self::B::staticVariable = self::f<dynamic>() : #t4;
+  dynamic v3 = self::B::staticVariable = self::B::staticVariable.+(self::f<dynamic>());
+  dynamic v4 = self::B::staticVariable = self::B::staticVariable.*(self::f<dynamic>());
+  dynamic v5 = self::B::staticVariable = self::B::staticVariable.&(self::f<dynamic>());
+  dynamic v6 = self::B::staticVariable = self::B::staticVariable.-(1);
+  dynamic v7 = let final dynamic #t5 = self::B::staticVariable in let final dynamic #t6 = self::B::staticVariable = #t5.-(1) in #t5;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.transformed.expect
new file mode 100644
index 0000000..84c4d62
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static.dart.strong.transformed.expect
@@ -0,0 +1,64 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  static field self::B staticVariable = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  operator +(self::C v) → self::A
+    return null;
+  operator -(core::int i) → self::B
+    return null;
+  operator *(self::B v) → self::B
+    return null;
+  operator &(self::A v) → self::C
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static field self::B topLevelVariable;
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test_topLevelVariable() → void {
+  self::topLevelVariable = self::f<self::B>();
+  self::topLevelVariable.{core::Object::==}(null) ?{self::B} self::topLevelVariable = self::f<self::B>() : null;
+  self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+  self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
+  self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
+  self::B v1 = self::topLevelVariable = self::f<self::B>();
+  self::B v2 = let final self::B #t1 = self::topLevelVariable in #t1.{core::Object::==}(null) ?{self::B} self::topLevelVariable = self::f<self::B>() : #t1;
+  self::A v3 = self::topLevelVariable = self::topLevelVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+  self::B v4 = self::topLevelVariable = self::topLevelVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  self::C v5 = self::topLevelVariable = self::topLevelVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  self::B v6 = self::topLevelVariable = self::topLevelVariable.{self::B::-}(1);
+  self::B v7 = let final self::B #t2 = self::topLevelVariable in let final self::B #t3 = self::topLevelVariable = #t2.{self::B::-}(1) in #t2;
+}
+static method test_staticVariable() → void {
+  self::B::staticVariable = self::f<self::B>();
+  self::B::staticVariable.{core::Object::==}(null) ?{self::B} self::B::staticVariable = self::f<self::B>() : null;
+  self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+  self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
+  self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
+  self::B v1 = self::B::staticVariable = self::f<self::B>();
+  self::B v2 = let final self::B #t4 = self::B::staticVariable in #t4.{core::Object::==}(null) ?{self::B} self::B::staticVariable = self::f<self::B>() : #t4;
+  self::A v3 = self::B::staticVariable = self::B::staticVariable.{self::B::+}(self::f<dynamic>() as{TypeError} self::C) as{TypeError} self::B;
+  self::B v4 = self::B::staticVariable = self::B::staticVariable.{self::B::*}(self::f<dynamic>() as{TypeError} self::B);
+  self::C v5 = self::B::staticVariable = self::B::staticVariable.{self::B::&}(self::f<dynamic>() as{TypeError} self::A);
+  self::B v6 = self::B::staticVariable = self::B::staticVariable.{self::B::-}(1);
+  self::B v7 = let final self::B #t5 = self::B::staticVariable in let final self::B #t6 = self::B::staticVariable = #t5.{self::B::-}(1) in #t5;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.direct.transformed.expect
new file mode 100644
index 0000000..7cf33f1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.direct.transformed.expect
@@ -0,0 +1,48 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int topLevelInt;
+static field core::num topLevelNum;
+static field core::double topLevelDouble;
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method test1() → void {
+  dynamic v1 = self::topLevelInt = self::getInt();
+  dynamic v2 = self::topLevelInt = self::getNum();
+  dynamic v4 = let final dynamic #t1 = self::topLevelInt in #t1.==(null) ? self::topLevelInt = self::getInt() : #t1;
+  dynamic v5 = let final dynamic #t2 = self::topLevelInt in #t2.==(null) ? self::topLevelInt = self::getNum() : #t2;
+  dynamic v7 = self::topLevelInt = self::topLevelInt.+(self::getInt());
+  dynamic v8 = self::topLevelInt = self::topLevelInt.+(self::getNum());
+  dynamic v10 = self::topLevelInt = self::topLevelInt.+(1);
+  dynamic v11 = let final dynamic #t3 = self::topLevelInt in let final dynamic #t4 = self::topLevelInt = #t3.+(1) in #t3;
+}
+static method test2() → void {
+  dynamic v1 = self::topLevelNum = self::getInt();
+  dynamic v2 = self::topLevelNum = self::getNum();
+  dynamic v3 = self::topLevelNum = self::getDouble();
+  dynamic v4 = let final dynamic #t5 = self::topLevelNum in #t5.==(null) ? self::topLevelNum = self::getInt() : #t5;
+  dynamic v5 = let final dynamic #t6 = self::topLevelNum in #t6.==(null) ? self::topLevelNum = self::getNum() : #t6;
+  dynamic v6 = let final dynamic #t7 = self::topLevelNum in #t7.==(null) ? self::topLevelNum = self::getDouble() : #t7;
+  dynamic v7 = self::topLevelNum = self::topLevelNum.+(self::getInt());
+  dynamic v8 = self::topLevelNum = self::topLevelNum.+(self::getNum());
+  dynamic v9 = self::topLevelNum = self::topLevelNum.+(self::getDouble());
+  dynamic v10 = self::topLevelNum = self::topLevelNum.+(1);
+  dynamic v11 = let final dynamic #t8 = self::topLevelNum in let final dynamic #t9 = self::topLevelNum = #t8.+(1) in #t8;
+}
+static method test3() → void {
+  dynamic v2 = self::topLevelDouble = self::getNum();
+  dynamic v3 = self::topLevelDouble = self::getDouble();
+  dynamic v5 = let final dynamic #t10 = self::topLevelDouble in #t10.==(null) ? self::topLevelDouble = self::getNum() : #t10;
+  dynamic v6 = let final dynamic #t11 = self::topLevelDouble in #t11.==(null) ? self::topLevelDouble = self::getDouble() : #t11;
+  dynamic v7 = self::topLevelDouble = self::topLevelDouble.+(self::getInt());
+  dynamic v8 = self::topLevelDouble = self::topLevelDouble.+(self::getNum());
+  dynamic v9 = self::topLevelDouble = self::topLevelDouble.+(self::getDouble());
+  dynamic v10 = self::topLevelDouble = self::topLevelDouble.+(1);
+  dynamic v11 = let final dynamic #t12 = self::topLevelDouble in let final dynamic #t13 = self::topLevelDouble = #t12.+(1) in #t12;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.strong.transformed.expect
new file mode 100644
index 0000000..68bfc44
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_assign_to_static_upwards.dart.strong.transformed.expect
@@ -0,0 +1,48 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::int topLevelInt;
+static field core::num topLevelNum;
+static field core::double topLevelDouble;
+static method getInt() → core::int
+  return 0;
+static method getNum() → core::num
+  return 0;
+static method getDouble() → core::double
+  return 0.0;
+static method test1() → void {
+  core::int v1 = self::topLevelInt = self::getInt();
+  core::num v2 = self::topLevelInt = self::getNum() as{TypeError} core::int;
+  core::int v4 = let final core::int #t1 = self::topLevelInt in #t1.{core::num::==}(null) ?{core::int} self::topLevelInt = self::getInt() : #t1;
+  core::num v5 = let final core::int #t2 = self::topLevelInt in #t2.{core::num::==}(null) ?{core::num} self::topLevelInt = self::getNum() as{TypeError} core::int : #t2;
+  core::int v7 = self::topLevelInt = self::topLevelInt.{core::num::+}(self::getInt());
+  core::num v8 = self::topLevelInt = self::topLevelInt.{core::num::+}(self::getNum()) as{TypeError} core::int;
+  core::int v10 = self::topLevelInt = self::topLevelInt.{core::num::+}(1);
+  core::int v11 = let final core::int #t3 = self::topLevelInt in let final core::int #t4 = self::topLevelInt = #t3.{core::num::+}(1) in #t3;
+}
+static method test2() → void {
+  core::int v1 = self::topLevelNum = self::getInt();
+  core::num v2 = self::topLevelNum = self::getNum();
+  core::double v3 = self::topLevelNum = self::getDouble();
+  core::num v4 = let final core::num #t5 = self::topLevelNum in #t5.{core::num::==}(null) ?{core::num} self::topLevelNum = self::getInt() : #t5;
+  core::num v5 = let final core::num #t6 = self::topLevelNum in #t6.{core::num::==}(null) ?{core::num} self::topLevelNum = self::getNum() : #t6;
+  core::num v6 = let final core::num #t7 = self::topLevelNum in #t7.{core::num::==}(null) ?{core::num} self::topLevelNum = self::getDouble() : #t7;
+  core::num v7 = self::topLevelNum = self::topLevelNum.{core::num::+}(self::getInt());
+  core::num v8 = self::topLevelNum = self::topLevelNum.{core::num::+}(self::getNum());
+  core::num v9 = self::topLevelNum = self::topLevelNum.{core::num::+}(self::getDouble());
+  core::num v10 = self::topLevelNum = self::topLevelNum.{core::num::+}(1);
+  core::num v11 = let final core::num #t8 = self::topLevelNum in let final core::num #t9 = self::topLevelNum = #t8.{core::num::+}(1) in #t8;
+}
+static method test3() → void {
+  core::num v2 = self::topLevelDouble = self::getNum() as{TypeError} core::double;
+  core::double v3 = self::topLevelDouble = self::getDouble();
+  core::num v5 = let final core::double #t10 = self::topLevelDouble in #t10.{core::num::==}(null) ?{core::num} self::topLevelDouble = self::getNum() as{TypeError} core::double : #t10;
+  core::double v6 = let final core::double #t11 = self::topLevelDouble in #t11.{core::num::==}(null) ?{core::double} self::topLevelDouble = self::getDouble() : #t11;
+  core::double v7 = self::topLevelDouble = self::topLevelDouble.{core::double::+}(self::getInt());
+  core::double v8 = self::topLevelDouble = self::topLevelDouble.{core::double::+}(self::getNum());
+  core::double v9 = self::topLevelDouble = self::topLevelDouble.{core::double::+}(self::getDouble());
+  core::double v10 = self::topLevelDouble = self::topLevelDouble.{core::double::+}(1);
+  core::double v11 = let final core::double #t12 = self::topLevelDouble in let final core::double #t13 = self::topLevelDouble = #t12.{core::double::+}(1) in #t12;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.direct.transformed.expect
new file mode 100644
index 0000000..0d86ccf
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_getter_setter_mismatch.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::int;
+  abstract set x(core::double value) → void;
+}
+class B extends self::A {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..ba4b43f
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_getter_overrides_setter.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(core::num value) → void;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract get x() → core::int;
+}
+class C extends self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.direct.transformed.expect
new file mode 100644
index 0000000..370dc25
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::num;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract set x(core::int value) → void;
+}
+class C extends self::B {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.strong.transformed.expect
new file mode 100644
index 0000000..1a3e8bf
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_field_override_setter_overrides_getter.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → core::num;
+}
+abstract class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  abstract set x(core::int value) → void;
+}
+class C extends self::B {
+  field core::num x = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.direct.transformed.expect
new file mode 100644
index 0000000..097abf7
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.direct.transformed.expect
@@ -0,0 +1,32 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field self::B b = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get c() → self::C
+    return null;
+  set c(self::C value) → void {}
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+static field dynamic a = new self::A::•();
+static field dynamic x = self::a.b.c;
+static field dynamic y = let final dynamic #t1 = self::a.b in let final dynamic #t2 = #t1.c in #t2.==(null) ? #t1.c = new self::D::•() : #t2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.strong.transformed.expect
new file mode 100644
index 0000000..b42ff08
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_accessor_ref.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field self::B b = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get c() → self::C
+    return null;
+  set c(self::C value) → void {}
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+static field self::A a = new self::A::•();
+static field self::C x = self::a.{self::A::b}.{self::B::c};
+static field self::C y = let final self::B #t1 = self::a.{self::A::b} in let final self::C #t2 = #t1.{self::B::c} in #t2.{core::Object::==}(null) ?{self::C} #t1.{self::B::c} = new self::D::•() : #t2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.direct.transformed.expect
new file mode 100644
index 0000000..7e940c1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.direct.transformed.expect
@@ -0,0 +1,30 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field self::B b = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field self::C c = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+static field dynamic a = new self::A::•();
+static field dynamic x = self::a.b.c;
+static field dynamic y = let final dynamic #t1 = self::a.b in let final dynamic #t2 = #t1.c in #t2.==(null) ? #t1.c = new self::D::•() : #t2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.strong.transformed.expect
new file mode 100644
index 0000000..80f34b9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field self::B b = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  field self::C c = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+static field self::A a = new self::A::•();
+static field self::C x = self::a.{self::A::b}.{self::B::c};
+static field self::C y = let final self::B #t1 = self::a.{self::A::b} in let final self::C #t2 = #t1.{self::B::c} in #t2.{core::Object::==}(null) ?{self::C} #t1.{self::B::c} = new self::D::•() : #t2;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.direct.transformed.expect
new file mode 100644
index 0000000..e431672
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic b = () → dynamic => self::x;
+  field dynamic c = () → dynamic => self::x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic a = new self::A::•();
+static field dynamic x = () → dynamic => self::a.b;
+static field dynamic y = () → dynamic => self::a.c;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
new file mode 100644
index 0000000..192bdbe
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic b = () → dynamic => self::x;
+  field () → dynamic c = () → dynamic => self::x;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A a = new self::A::•();
+static field dynamic x = () → dynamic => self::a.{self::A::b};
+static field () → () → dynamic y = () → () → dynamic => self::a.{self::A::c};
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:11:69: Error: Can't infer the type of 'b': circularity found during type inference.
+Specify the type explicitly.
+  var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ b = /*@returnType=dynamic*/ () =>
+                                                                    ^", "pkg/front_end/testcases/inference_new/infer_instance_field_ref_circular.dart:17:67: Error: Can't infer the type of 'x': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
+                                                                  ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_logical.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_logical.dart.direct.transformed.expect
new file mode 100644
index 0000000..02c47e9
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_logical.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic x = self::f<dynamic>() || self::f<dynamic>();
+static field dynamic y = self::f<dynamic>() && self::f<dynamic>();
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  dynamic x = self::f<dynamic>() || self::f<dynamic>();
+  dynamic y = self::f<dynamic>() && self::f<dynamic>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_logical.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_logical.dart.strong.transformed.expect
new file mode 100644
index 0000000..b5ead6e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_logical.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::bool x = self::f<core::bool>() || self::f<core::bool>();
+static field core::bool y = self::f<core::bool>() && self::f<core::bool>();
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  core::bool x = self::f<core::bool>() || self::f<core::bool>();
+  core::bool y = self::f<core::bool>() && self::f<core::bool>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.direct.transformed.expect
new file mode 100644
index 0000000..147a6a5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → void {}
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  method f() → dynamic {}
+}
+static field dynamic x = new self::C::•().f();
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.strong.transformed.expect
new file mode 100644
index 0000000..9a42ff3
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/infer_use_of_void.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → void {}
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  method f() → void {}
+}
+static field void x = new self::C::•().{self::C::f}();
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.direct.transformed.expect
new file mode 100644
index 0000000..321c94e
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static field core::int i;
+static field core::String s;
+static field dynamic x = self::i = self::s;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..47d5c06
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static field core::int i;
+static field core::String s;
+static field core::String x = self::i = let final core::String #t1 = self::s in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/inference_new/invalid_assignment_during_toplevel_inference.dart:9:62: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+var /*@topType=String*/ x = i = /*@error=InvalidAssignment*/ s;
+                                                             ^";
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.direct.transformed.expect
new file mode 100644
index 0000000..c2df0e3
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic x = <dynamic>[null];
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.transformed.expect
new file mode 100644
index 0000000..566cf74
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/list_literals_can_infer_null_top_level.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::Null> x = <core::Null>[null];
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.direct.transformed.expect
new file mode 100644
index 0000000..aaecc4d
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library test;
+import self as self;
+
+static field dynamic x = <dynamic, dynamic>{null: null};
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.transformed.expect
new file mode 100644
index 0000000..8c2f105
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/map_literals_can_infer_null_top_level.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::Map<core::Null, core::Null> x = <core::Null, core::Null>{null: null};
+static method main() → dynamic {
+  self::x;
+}
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.direct.transformed.expect
new file mode 100644
index 0000000..8d4f115
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.direct.transformed.expect
@@ -0,0 +1,48 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class I1 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(core::int i) → void;
+}
+abstract class I2 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(core::Object o) → void;
+}
+abstract class C extends core::Object implements self::I1, self::I2 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f(core::Object o) → void {}
+}
+abstract class E extends core::Object implements self::I2, self::I1 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends self::E {
+  synthetic constructor •() → void
+    : super self::E::•()
+    ;
+  method f(core::Object o) → void {}
+}
+static method g1(self::C c) → void {
+  c.f("hi");
+}
+static method g2(self::E e) → void {
+  e.f("hi");
+}
+static method main() → dynamic {
+  self::g1(new self::D::•());
+  self::g2(new self::F::•());
+}
diff --git a/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.strong.transformed.expect
new file mode 100644
index 0000000..eec2396
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/multiple_interface_inheritance.dart.strong.transformed.expect
@@ -0,0 +1,49 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class I1 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(core::int i) → void;
+}
+abstract class I2 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(core::Object o) → void;
+}
+abstract class C extends core::Object implements self::I1, self::I2 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub method f(core::Object o) → void;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f(core::Object o) → void {}
+}
+abstract class E extends core::Object implements self::I2, self::I1 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends self::E {
+  synthetic constructor •() → void
+    : super self::E::•()
+    ;
+  method f(core::Object o) → void {}
+}
+static method g1(self::C c) → void {
+  c.{self::C::f}("hi");
+}
+static method g2(self::E e) → void {
+  e.{self::I2::f}("hi");
+}
+static method main() → dynamic {
+  self::g1(new self::D::•());
+  self::g2(new self::F::•());
+}
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.direct.transformed.expect
new file mode 100644
index 0000000..1bb7b06
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.direct.transformed.expect
@@ -0,0 +1,65 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::C
+    return null;
+  operator *(self::D value) → self::C
+    return null;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::E
+    return null;
+  operator *(self::F value) → self::E
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class G extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get target() → self::A
+    return null;
+  set target(self::B value) → void {}
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test1(self::G g) → void {
+  let final dynamic #t1 = g in #t1.target = #t1.target.*(self::f<dynamic>());
+  dynamic x = let final dynamic #t2 = g in #t2.target = #t2.target.*(self::f<dynamic>());
+}
+static method test2(self::G g) → void {
+  let final dynamic #t3 = g in #t3.target = #t3.target.+(1);
+  dynamic x = let final dynamic #t4 = g in #t4.target = #t4.target.+(1);
+}
+static method test3(self::G g) → void {
+  let final dynamic #t5 = g in #t5.target = #t5.target.+(1);
+  dynamic x = let final dynamic #t6 = g in let final dynamic #t7 = #t6.target in let final dynamic #t8 = #t6.target = #t7.+(1) in #t7;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.transformed.expect
new file mode 100644
index 0000000..1bb49c8
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_assign_combiner.dart.strong.transformed.expect
@@ -0,0 +1,65 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::C
+    return null;
+  operator *(self::D value) → self::C
+    return null;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::E
+    return null;
+  operator *(self::F value) → self::E
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class G extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get target() → self::A
+    return null;
+  set target(self::B value) → void {}
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test1(self::G g) → void {
+  let final self::G #t1 = g in #t1.{self::G::target} = #t1.{self::G::target}.{self::A::*}(self::f<dynamic>() as{TypeError} self::D);
+  self::C x = let final self::G #t2 = g in #t2.{self::G::target} = #t2.{self::G::target}.{self::A::*}(self::f<dynamic>() as{TypeError} self::D);
+}
+static method test2(self::G g) → void {
+  let final self::G #t3 = g in #t3.{self::G::target} = #t3.{self::G::target}.{self::A::+}(1);
+  self::C x = let final self::G #t4 = g in #t4.{self::G::target} = #t4.{self::G::target}.{self::A::+}(1);
+}
+static method test3(self::G g) → void {
+  let final self::G #t5 = g in #t5.{self::G::target} = #t5.{self::G::target}.{self::A::+}(1);
+  self::A x = let final self::G #t6 = g in let final self::A #t7 = #t6.{self::G::target} in let final self::C #t8 = #t6.{self::G::target} = #t7.{self::A::+}(1) in #t7;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.direct.transformed.expect
new file mode 100644
index 0000000..a0e3f31
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::int field = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get getter() → core::int
+    return 0;
+  method function() → core::int
+    return 0;
+}
+static field self::C c = new self::C::•();
+static field dynamic field_ref = self::c.field;
+static field dynamic getter_ref = self::c.getter;
+static field dynamic function_ref = self::c.function;
+static field dynamic field_ref_list = <dynamic>[self::c.field];
+static field dynamic getter_ref_list = <dynamic>[self::c.getter];
+static field dynamic function_ref_list = <dynamic>[self::c.function];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.strong.transformed.expect
new file mode 100644
index 0000000..fecf831
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/property_get_toplevel.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::int field = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get getter() → core::int
+    return 0;
+  method function() → core::int
+    return 0;
+}
+static field self::C c = new self::C::•();
+static field core::int field_ref = self::c.{self::C::field};
+static field core::int getter_ref = self::c.{self::C::getter};
+static field () → core::int function_ref = self::c.{self::C::function};
+static field core::List<core::int> field_ref_list = <core::int>[self::c.{self::C::field}];
+static field core::List<core::int> getter_ref_list = <core::int>[self::c.{self::C::getter}];
+static field core::List<() → core::int> function_ref_list = <() → core::int>[self::c.{self::C::function}];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.direct.transformed.expect
new file mode 100644
index 0000000..3b7b792
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.direct.transformed.expect
@@ -0,0 +1,60 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::C
+    return null;
+  operator *(self::D value) → self::C
+    return null;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::E
+    return null;
+  operator *(self::F value) → self::E
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static get target() → self::A
+  return null;
+static set target(self::B value) → void {}
+static method test1() → void {
+  self::target = self::target.*(self::f<dynamic>());
+  dynamic x = self::target = self::target.*(self::f<dynamic>());
+}
+static method test2() → void {
+  self::target = self::target.+(1);
+  dynamic x = self::target = self::target.+(1);
+}
+static method test3() → void {
+  self::target = self::target.+(1);
+  dynamic x = let final dynamic #t1 = self::target in let final dynamic #t2 = self::target = #t1.+(1) in #t1;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect
new file mode 100644
index 0000000..e2277e6
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect
@@ -0,0 +1,60 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::C
+    return null;
+  operator *(self::D value) → self::C
+    return null;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int value) → self::E
+    return null;
+  operator *(self::F value) → self::E
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static get target() → self::A
+  return null;
+static set target(self::B value) → void {}
+static method test1() → void {
+  self::target = self::target.{self::A::*}(self::f<dynamic>() as{TypeError} self::D);
+  self::C x = self::target = self::target.{self::A::*}(self::f<dynamic>() as{TypeError} self::D);
+}
+static method test2() → void {
+  self::target = self::target.{self::A::+}(1);
+  self::C x = self::target = self::target.{self::A::+}(1);
+}
+static method test3() → void {
+  self::target = self::target.{self::A::+}(1);
+  self::A x = let final self::A #t1 = self::target in let final self::C #t2 = self::target = #t1.{self::A::+}(1) in #t1;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.direct.transformed.expect
new file mode 100644
index 0000000..5124459
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic x = () → dynamic => self::f() ? self::y : self::z;
+static field dynamic y = () → dynamic => self::x;
+static field dynamic z = () → dynamic => self::x;
+static method f() → core::bool
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
new file mode 100644
index 0000000..7f9a899
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/strongly_connected_component.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic x = () → dynamic => self::f() ?{dynamic} self::y : self::z;
+static field dynamic y = () → dynamic => self::x;
+static field () → dynamic z = () → dynamic => self::x;
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/inference_new/strongly_connected_component.dart:19:67: Error: Can't infer the type of 'y': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ y = /*@returnType=dynamic*/ () =>
+                                                                  ^", "pkg/front_end/testcases/inference_new/strongly_connected_component.dart:17:67: Error: Can't infer the type of 'x': circularity found during type inference.
+Specify the type explicitly.
+var /*@topType=dynamic*/ /*@error=CantInferTypeDueToCircularity*/ x = /*@returnType=dynamic*/ () =>
+                                                                  ^"]/* from null */;
+static method f() → core::bool
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.direct.transformed.expect
new file mode 100644
index 0000000..d30ced1
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int x) → core::num
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  operator [](core::Object x) → core::int
+    return null;
+  method h() → void {
+    dynamic x = super.{self::B::[]}(self::f<dynamic>());
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.transformed.expect
new file mode 100644
index 0000000..78e7bfb
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int x) → core::num
+    return null;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  operator [](core::Object x) → core::int
+    return null;
+  method h() → void {
+    core::num x = super.{self::B::[]}(self::f<core::int>());
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.direct.transformed.expect
new file mode 100644
index 0000000..ee237ad
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.direct.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<T extends core::Object> extends self::D<self::E::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](self::E<self::B::T> x) → self::D<self::B::T>
+    return null;
+}
+class C<U extends core::Object> extends self::B<asy::Future<self::C::U>> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  operator [](core::Object x) → self::E<asy::Future<self::C::U>>
+    return null;
+  method h() → void {
+    dynamic x = super.{self::B::[]}(self::f<dynamic>());
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.transformed.expect
new file mode 100644
index 0000000..b061ba0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/super_index_get_substitution.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class D<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<T extends core::Object> extends self::D<self::E::T> {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](generic-covariant-impl generic-covariant-interface self::E<self::B::T> x) → self::D<self::B::T>
+    return null;
+}
+class C<U extends core::Object> extends self::B<asy::Future<self::C::U>> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  operator [](generic-covariant-impl core::Object x) → self::E<asy::Future<self::C::U>>
+    return null;
+  method h() → void {
+    self::D<asy::Future<self::C::U>> x = super.{self::B::[]}(self::f<self::E<asy::Future<self::C::U>>>());
+  }
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/switch.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/switch.dart.direct.transformed.expect
new file mode 100644
index 0000000..2cafaef
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/switch.dart.direct.transformed.expect
@@ -0,0 +1,29 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test(self::C<core::int> x) → void {
+  #L1:
+  switch(x) {
+    #L2:
+    case const self::C::•<dynamic>():
+      {
+        dynamic y = 0;
+        break #L1;
+      }
+    #L3:
+    default:
+      {
+        dynamic y = 0;
+        break #L1;
+      }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/switch.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/switch.dart.strong.transformed.expect
new file mode 100644
index 0000000..1c6f5e5
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/switch.dart.strong.transformed.expect
@@ -0,0 +1,29 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test(self::C<core::int> x) → void {
+  #L1:
+  switch(x) {
+    #L2:
+    case const self::C::•<core::int>():
+      {
+        core::int y = 0;
+        break #L1;
+      }
+    #L3:
+    default:
+      {
+        core::int y = 0;
+        break #L1;
+      }
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.direct.transformed.expect
new file mode 100644
index 0000000..cd980ee
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.direct.transformed.expect
@@ -0,0 +1,53 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+abstract class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → self::A;
+}
+abstract class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → self::B;
+}
+abstract class F extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → core::Object;
+}
+abstract class G extends core::Object implements self::D, self::E, self::F {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class H extends self::G {
+  synthetic constructor •() → void
+    : super self::G::•()
+    ;
+  method foo() → self::C
+    return new self::C::•();
+}
+static field dynamic x = self::bar().foo();
+static method bar() → self::G
+  return new self::H::•();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.strong.transformed.expect
new file mode 100644
index 0000000..35ad473
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/top_level_field_depends_on_multiple_inheritance.dart.strong.transformed.expect
@@ -0,0 +1,54 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+abstract class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → self::A;
+}
+abstract class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → self::B;
+}
+abstract class F extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → core::Object;
+}
+abstract class G extends core::Object implements self::D, self::E, self::F {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract forwarding-stub method foo() → self::B;
+}
+class H extends self::G {
+  synthetic constructor •() → void
+    : super self::G::•()
+    ;
+  method foo() → self::C
+    return new self::C::•();
+}
+static field self::B x = self::bar().{self::G::foo}();
+static method bar() → self::G
+  return new self::H::•();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.direct.transformed.expect
new file mode 100644
index 0000000..db7a7bd
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic v = self::f.call(() → dynamic {
+  return 1;
+});
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.strong.transformed.expect
new file mode 100644
index 0000000..5c16415
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> v = self::f.call<core::int>(() → core::int {
+  return 1;
+});
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.direct.transformed.expect
new file mode 100644
index 0000000..db7a7bd
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic v = self::f.call(() → dynamic {
+  return 1;
+});
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.strong.transformed.expect
new file mode 100644
index 0000000..5c16415
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/unsafe_block_closure_inference_function_call_explicit_type_param_via_expr2.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field core::List<core::int> v = self::f.call<core::int>(() → core::int {
+  return 1;
+});
+static method f<T extends core::Object>(() → self::f::T g) → core::List<self::f::T>
+  return <self::f::T>[g.call()];
+static method main() → dynamic {
+  self::v;
+}
diff --git a/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.direct.transformed.expect
new file mode 100644
index 0000000..9a95c8a
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field dynamic y = self::run<dynamic>(self::printRunning);
+static method run<T extends core::Object>(() → self::run::T f) → self::run::T {
+  core::print("running");
+  dynamic t = f.call();
+  core::print("done running");
+  return t;
+}
+static method printRunning() → void {
+  core::print("running");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.strong.transformed.expect
new file mode 100644
index 0000000..fc015dc
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/void_return_type_subtypes_dynamic.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static field void y = self::run<void>(self::printRunning);
+static method run<T extends core::Object>(() → self::run::T f) → self::run::T {
+  core::print("running");
+  self::run::T t = f.call();
+  core::print("done running");
+  return t;
+}
+static method printRunning() → void {
+  core::print("running");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/while_loop.dart.direct.transformed.expect b/pkg/front_end/testcases/inference_new/while_loop.dart.direct.transformed.expect
new file mode 100644
index 0000000..93db6ac0
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/while_loop.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  while (self::f<dynamic>()) {
+    dynamic x = 0;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/while_loop.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/while_loop.dart.strong.transformed.expect
new file mode 100644
index 0000000..411b444
--- /dev/null
+++ b/pkg/front_end/testcases/inference_new/while_loop.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method f<T extends core::Object>() → self::f::T
+  return null;
+static method test() → void {
+  while (self::f<core::bool>()) {
+    core::int x = 0;
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.direct.transformed.expect
new file mode 100644
index 0000000..90d33dd
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends self::B<self::D::X, self::D::Y>, Y extends self::C<self::D::X, self::D::Y>, Z extends (self::D::Y) → self::D::X, W extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::D<dynamic, dynamic, dynamic, dynamic> d;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.strong.transformed.expect
new file mode 100644
index 0000000..e209715
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/all_steps.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends self::B<self::D::X, self::D::Y>, Y extends self::C<self::D::X, self::D::Y>, Z extends (self::D::Y) → self::D::X, W extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::D<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>, (core::Null) → self::B<dynamic, dynamic>, core::num> d;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.direct.transformed.expect
new file mode 100644
index 0000000..4a8c9a0
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    col::LinkedListEntry<dynamic> bar;
+  }
+}
+static method main() → dynamic {
+  col::LinkedListEntry<dynamic> bar;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.transformed.expect
new file mode 100644
index 0000000..8c50708
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_generic_classes_from_dill.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    col::LinkedListEntry<col::LinkedListEntry<dynamic>> bar;
+  }
+}
+static method main() → dynamic {
+  col::LinkedListEntry<col::LinkedListEntry<dynamic>> bar;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.direct.transformed.expect
new file mode 100644
index 0000000..473030f
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    dynamic a = <self::A<dynamic>>[];
+  }
+}
+static method main() → dynamic {
+  dynamic a = <self::A<dynamic>>[];
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.strong.transformed.expect
new file mode 100644
index 0000000..7f1bc8a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    core::List<self::A<core::num>> a = <self::A<core::num>>[];
+  }
+}
+static method main() → dynamic {
+  core::List<self::A<core::num>> a = <self::A<core::num>>[];
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.direct.transformed.expect
new file mode 100644
index 0000000..b96b592
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<U extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method fun() → dynamic {
+    core::List<self::A<self::B::U>> foo = <self::A<self::B::U>>[];
+    core::List<self::A<core::num>> bar = <self::A<core::num>>[];
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.strong.transformed.expect
new file mode 100644
index 0000000..b96b592
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_list_with_generic_argument.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<U extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method fun() → dynamic {
+    core::List<self::A<self::B::U>> foo = <self::A<self::B::U>>[];
+    core::List<self::A<core::num>> bar = <self::A<core::num>>[];
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.direct.transformed.expect
new file mode 100644
index 0000000..571bb1b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    dynamic a = <self::A<dynamic>, self::A<dynamic>>{};
+  }
+}
+static method main() → dynamic {
+  dynamic a = <self::A<dynamic>, self::A<dynamic>>{};
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.strong.transformed.expect
new file mode 100644
index 0000000..7a9a472
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_literal_map.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    core::Map<self::A<core::num>, self::A<core::num>> a = <self::A<core::num>, self::A<core::num>>{};
+  }
+}
+static method main() → dynamic {
+  core::Map<self::A<core::num>, self::A<core::num>> a = <self::A<core::num>, self::A<core::num>>{};
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..b7936f1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method fun() → dynamic {
+    self::A<dynamic> a;
+    col::DoubleLinkedQueue<dynamic> c;
+  }
+}
+static method main() → dynamic {
+  self::A<dynamic> a;
+  col::DoubleLinkedQueue<dynamic> c;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..b7936f1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_omitted_bound.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method fun() → dynamic {
+    self::A<dynamic> a;
+    col::DoubleLinkedQueue<dynamic> c;
+  }
+}
+static method main() → dynamic {
+  self::A<dynamic> a;
+  col::DoubleLinkedQueue<dynamic> c;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..174756c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends self::A<self::A::T>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    self::A<dynamic> a;
+  }
+}
+static method main() → dynamic {
+  self::A<dynamic> a;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..3657fb3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_super_bounded_type.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends self::A<self::A::T>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    self::A<self::A<dynamic>> a;
+  }
+}
+static method main() → dynamic {
+  self::A<self::A<dynamic>> a;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.direct.transformed.expect
new file mode 100644
index 0000000..7d3b891
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    dynamic a = <(dynamic) → dynamic>[];
+  }
+}
+static method main() → dynamic {
+  dynamic a = <(dynamic) → dynamic>[];
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.transformed.expect
new file mode 100644
index 0000000..00162ec
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    core::List<(core::num) → dynamic> a = <(core::num) → dynamic>[];
+  }
+}
+static method main() → dynamic {
+  core::List<(core::num) → dynamic> a = <(core::num) → dynamic>[];
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.direct.transformed.expect
new file mode 100644
index 0000000..52cb506
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object> = (T) → dynamic;
+class B<U extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method fun() → dynamic {
+    core::List<(self::B::U) → dynamic> foo = <(self::B::U) → dynamic>[];
+    core::List<(core::num) → dynamic> bar = <(core::num) → dynamic>[];
+  }
+}
+static method main() → dynamic {
+  core::List<(core::num) → dynamic> bar = <(core::num) → dynamic>[];
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.transformed.expect
new file mode 100644
index 0000000..52cb506
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_list_with_generic_argument.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object> = (T) → dynamic;
+class B<U extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method fun() → dynamic {
+    core::List<(self::B::U) → dynamic> foo = <(self::B::U) → dynamic>[];
+    core::List<(core::num) → dynamic> bar = <(core::num) → dynamic>[];
+  }
+}
+static method main() → dynamic {
+  core::List<(core::num) → dynamic> bar = <(core::num) → dynamic>[];
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.direct.transformed.expect
new file mode 100644
index 0000000..fd38c09
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    dynamic a = <(dynamic) → dynamic, (dynamic) → dynamic>{};
+  }
+}
+static method main() → dynamic {
+  dynamic a = <(dynamic) → dynamic, (dynamic) → dynamic>{};
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.transformed.expect
new file mode 100644
index 0000000..f63ba9a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_literal_map.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    core::Map<(core::num) → dynamic, (core::num) → dynamic> a = <(core::num) → dynamic, (core::num) → dynamic>{};
+  }
+}
+static method main() → dynamic {
+  core::Map<(core::num) → dynamic, (core::num) → dynamic> a = <(core::num) → dynamic, (core::num) → dynamic>{};
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..ff7a612
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object> = (T) → dynamic;
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    (dynamic) → dynamic a;
+  }
+}
+static method main() → dynamic {
+  (dynamic) → dynamic a;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..ff7a612
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_omitted_bound.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object> = (T) → dynamic;
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    (dynamic) → dynamic a;
+  }
+}
+static method main() → dynamic {
+  (dynamic) → dynamic a;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..1712b9b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/body_typedef_super_bounded_type.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object> = (T) → dynamic;
+typedef B<U extends (U) → dynamic> = (U) → dynamic;
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic {
+    (dynamic) → dynamic b;
+  }
+}
+static method main() → dynamic {
+  (dynamic) → dynamic b;
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.direct.transformed.expect
new file mode 100644
index 0000000..b2e548c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C<X extends core::num, Y extends (self::C::X) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C<dynamic, dynamic> c;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.strong.transformed.expect
new file mode 100644
index 0000000..7752f4e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C<X extends core::num, Y extends (self::C::X) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C<core::num, (core::Null) → void> c;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.direct.transformed.expect
new file mode 100644
index 0000000..88dc108
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C<X extends core::num, Y extends (self::C::X) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic lc = <self::C<dynamic, dynamic>>[];
+static field dynamic mc = <self::C<dynamic, dynamic>, self::C<dynamic, dynamic>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.strong.transformed.expect
new file mode 100644
index 0000000..a18fd3d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_dependence_in_literals.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C<X extends core::num, Y extends (self::C::X) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<self::C<core::num, (core::Null) → void>> lc = <self::C<core::num, (core::Null) → void>>[];
+static field core::Map<self::C<core::num, (core::Null) → void>, self::C<core::num, (core::Null) → void>> mc = <self::C<core::num, (core::Null) → void>, self::C<core::num, (core::Null) → void>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.direct.transformed.expect
new file mode 100644
index 0000000..17cca3b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class D<X extends (self::D::X, self::D::Y) → void, Y extends (self::D::X, self::D::Y) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends (self::E::X) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::D<dynamic, dynamic> d;
+static field self::E<dynamic> e;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.strong.transformed.expect
new file mode 100644
index 0000000..b3fcc39
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class D<X extends (self::D::X, self::D::Y) → void, Y extends (self::D::X, self::D::Y) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends (self::E::X) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::D<(core::Null, core::Null) → void, (core::Null, core::Null) → void> d;
+static field self::E<(core::Null) → void> e;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.direct.transformed.expect
new file mode 100644
index 0000000..803b7ee
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class D<X extends (self::D::X, self::D::Y) → void, Y extends (self::D::X, self::D::Y) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends (self::E::X) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic ld = <self::D<dynamic, dynamic>>[];
+static field dynamic md = <self::D<dynamic, dynamic>, self::D<dynamic, dynamic>>{};
+static field dynamic le = <self::E<dynamic>>[];
+static field dynamic me = <self::E<dynamic>, self::E<dynamic>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.strong.transformed.expect
new file mode 100644
index 0000000..1797ecd
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/contravariant_mutual_dependence_in_literals.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class D<X extends (self::D::X, self::D::Y) → void, Y extends (self::D::X, self::D::Y) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends (self::E::X) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<self::D<(core::Null, core::Null) → void, (core::Null, core::Null) → void>> ld = <self::D<(core::Null, core::Null) → void, (core::Null, core::Null) → void>>[];
+static field core::Map<self::D<(core::Null, core::Null) → void, (core::Null, core::Null) → void>, self::D<(core::Null, core::Null) → void, (core::Null, core::Null) → void>> md = <self::D<(core::Null, core::Null) → void, (core::Null, core::Null) → void>, self::D<(core::Null, core::Null) → void, (core::Null, core::Null) → void>>{};
+static field core::List<self::E<(core::Null) → void>> le = <self::E<(core::Null) → void>>[];
+static field core::Map<self::E<(core::Null) → void>, self::E<(core::Null) → void>> me = <self::E<(core::Null) → void>, self::E<(core::Null) → void>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.direct.transformed.expect
new file mode 100644
index 0000000..2d50f0b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends self::A<self::C::X>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends core::num, Y extends self::A<self::D::X>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends core::Object, Y extends () → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F<X extends core::num, Y extends () → self::F::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C<dynamic, dynamic> c;
+static field self::D<dynamic, dynamic> d;
+static field self::E<dynamic, dynamic> e;
+static field self::F<dynamic, dynamic> f;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.strong.transformed.expect
new file mode 100644
index 0000000..dfad499
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends self::A<self::C::X>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends core::num, Y extends self::A<self::D::X>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends core::Object, Y extends () → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F<X extends core::num, Y extends () → self::F::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C<dynamic, self::A<dynamic>> c;
+static field self::D<core::num, self::A<core::num>> d;
+static field self::E<dynamic, () → dynamic> e;
+static field self::F<core::num, () → core::num> f;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.direct.transformed.expect
new file mode 100644
index 0000000..f3f4e88
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.direct.transformed.expect
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends self::A<self::C::X>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends core::num, Y extends self::A<self::D::X>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends core::Object, Y extends () → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F<X extends core::num, Y extends () → self::F::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic lc = <self::C<dynamic, dynamic>>[];
+static field dynamic mc = <self::C<dynamic, dynamic>, self::C<dynamic, dynamic>>{};
+static field dynamic ld = <self::D<dynamic, dynamic>>[];
+static field dynamic md = <self::D<dynamic, dynamic>, self::D<dynamic, dynamic>>{};
+static field dynamic le = <self::E<dynamic, dynamic>>[];
+static field dynamic me = <self::E<dynamic, dynamic>, self::E<dynamic, dynamic>>{};
+static field dynamic lf = <self::F<dynamic, dynamic>>[];
+static field dynamic mf = <self::F<dynamic, dynamic>, self::F<dynamic, dynamic>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.strong.transformed.expect
new file mode 100644
index 0000000..e2ae82b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_dependence_in_literals.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends self::A<self::C::X>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends core::num, Y extends self::A<self::D::X>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends core::Object, Y extends () → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F<X extends core::num, Y extends () → self::F::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<self::C<dynamic, self::A<dynamic>>> lc = <self::C<dynamic, self::A<dynamic>>>[];
+static field core::Map<self::C<dynamic, self::A<dynamic>>, self::C<dynamic, self::A<dynamic>>> mc = <self::C<dynamic, self::A<dynamic>>, self::C<dynamic, self::A<dynamic>>>{};
+static field core::List<self::D<core::num, self::A<core::num>>> ld = <self::D<core::num, self::A<core::num>>>[];
+static field core::Map<self::D<core::num, self::A<core::num>>, self::D<core::num, self::A<core::num>>> md = <self::D<core::num, self::A<core::num>>, self::D<core::num, self::A<core::num>>>{};
+static field core::List<self::E<dynamic, () → dynamic>> le = <self::E<dynamic, () → dynamic>>[];
+static field core::Map<self::E<dynamic, () → dynamic>, self::E<dynamic, () → dynamic>> me = <self::E<dynamic, () → dynamic>, self::E<dynamic, () → dynamic>>{};
+static field core::List<self::F<core::num, () → core::num>> lf = <self::F<core::num, () → core::num>>[];
+static field core::Map<self::F<core::num, () → core::num>, self::F<core::num, () → core::num>> mf = <self::F<core::num, () → core::num>, self::F<core::num, () → core::num>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.direct.transformed.expect
new file mode 100644
index 0000000..d6cc852
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.direct.transformed.expect
@@ -0,0 +1,33 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends self::B<self::D::X, self::D::Y>, Y extends self::C<self::D::X, self::D::Y>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends self::B<self::E::X, self::E::Y>, Y extends () → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F<X extends () → self::F::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::D<dynamic, dynamic> d;
+static field self::E<dynamic, dynamic> e;
+static field self::F<dynamic> f;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.strong.transformed.expect
new file mode 100644
index 0000000..1ebe886
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends self::B<self::D::X, self::D::Y>, Y extends self::C<self::D::X, self::D::Y>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends self::B<self::E::X, self::E::Y>, Y extends () → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F<X extends () → self::F::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::D<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>> d;
+static field self::E<self::B<dynamic, dynamic>, () → dynamic> e;
+static field self::F<() → dynamic> f;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.direct.transformed.expect
new file mode 100644
index 0000000..bc1bfe2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.direct.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends self::B<self::D::X, self::D::Y>, Y extends self::C<self::D::X, self::D::Y>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends self::B<self::E::X, self::E::Y>, Y extends () → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F<X extends () → self::F::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic ld = <self::D<dynamic, dynamic>>[];
+static field dynamic md = <self::D<dynamic, dynamic>, self::D<dynamic, dynamic>>{};
+static field dynamic le = <self::E<dynamic, dynamic>>[];
+static field dynamic me = <self::E<dynamic, dynamic>, self::E<dynamic, dynamic>>{};
+static field dynamic lf = <self::F<dynamic>>[];
+static field dynamic mf = <self::F<dynamic>, self::F<dynamic>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.strong.transformed.expect
new file mode 100644
index 0000000..5dd347a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/covariant_mutual_dependence_in_literals.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends self::B<self::D::X, self::D::Y>, Y extends self::C<self::D::X, self::D::Y>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends self::B<self::E::X, self::E::Y>, Y extends () → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F<X extends () → self::F::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<self::D<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>>> ld = <self::D<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>>>[];
+static field core::Map<self::D<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>>, self::D<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>>> md = <self::D<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>>, self::D<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>>>{};
+static field core::List<self::E<self::B<dynamic, dynamic>, () → dynamic>> le = <self::E<self::B<dynamic, dynamic>, () → dynamic>>[];
+static field core::Map<self::E<self::B<dynamic, dynamic>, () → dynamic>, self::E<self::B<dynamic, dynamic>, () → dynamic>> me = <self::E<self::B<dynamic, dynamic>, () → dynamic>, self::E<self::B<dynamic, dynamic>, () → dynamic>>{};
+static field core::List<self::F<() → dynamic>> lf = <self::F<() → dynamic>>[];
+static field core::Map<self::F<() → dynamic>, self::F<() → dynamic>> mf = <self::F<() → dynamic>, self::F<() → dynamic>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.direct.transformed.expect
new file mode 100644
index 0000000..50c5cd5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends (self::C::X) → self::C::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends core::num, Y extends (self::D::X) → self::D::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C<dynamic, dynamic> c;
+static field self::D<dynamic, dynamic> d;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.strong.transformed.expect
new file mode 100644
index 0000000..5e74c50
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends (self::C::X) → self::C::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends core::num, Y extends (self::D::X) → self::D::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C<dynamic, (core::Null) → dynamic> c;
+static field self::D<core::num, (core::Null) → core::num> d;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.direct.transformed.expect
new file mode 100644
index 0000000..3d63194
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends (self::C::X) → self::C::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends core::num, Y extends (self::D::X) → self::D::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic lc = <self::C<dynamic, dynamic>>[];
+static field dynamic mc = <self::C<dynamic, dynamic>, self::C<dynamic, dynamic>>{};
+static field dynamic ld = <self::D<dynamic, dynamic>>[];
+static field dynamic md = <self::D<dynamic, dynamic>, self::D<dynamic, dynamic>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.strong.transformed.expect
new file mode 100644
index 0000000..454cf25
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/dependence_in_literals.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends (self::C::X) → self::C::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends core::num, Y extends (self::D::X) → self::D::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<self::C<dynamic, (core::Null) → dynamic>> lc = <self::C<dynamic, (core::Null) → dynamic>>[];
+static field core::Map<self::C<dynamic, (core::Null) → dynamic>, self::C<dynamic, (core::Null) → dynamic>> mc = <self::C<dynamic, (core::Null) → dynamic>, self::C<dynamic, (core::Null) → dynamic>>{};
+static field core::List<self::D<core::num, (core::Null) → core::num>> ld = <self::D<core::num, (core::Null) → core::num>>[];
+static field core::Map<self::D<core::num, (core::Null) → core::num>, self::D<core::num, (core::Null) → core::num>> md = <self::D<core::num, (core::Null) → core::num>, self::D<core::num, (core::Null) → core::num>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.direct.transformed.expect
new file mode 100644
index 0000000..2a54655
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:collection" as col;
+
+static field col::LinkedListEntry<col::LinkedListEntry<dynamic>> y;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.transformed.expect
new file mode 100644
index 0000000..2a54655
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/generic_classes_from_dill.dart.strong.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:collection" as col;
+
+static field col::LinkedListEntry<col::LinkedListEntry<dynamic>> y;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..a268770
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::A<dynamic> a = new self::A::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..b63980f
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_constrained_by_bound.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::A<core::num> a = new self::A::•<core::num>();
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..7d9fe60
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  new self::A::•<dynamic>();
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..bf8ac07
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_defaults_to_bound.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  new self::A::•<core::num>();
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.direct.transformed.expect
new file mode 100644
index 0000000..964c2f9
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::num, S extends core::List<self::B::T>> extends self::A<self::B::T> {
+  constructor •([self::B::T x = null]) → void
+    : super self::A::•() {}
+}
+static method main() → dynamic {
+  self::B<dynamic, dynamic> x;
+  dynamic y = new self::B::•<dynamic, dynamic>(3);
+  self::A<core::int> z = new self::B::•<dynamic, dynamic>();
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.strong.transformed.expect
new file mode 100644
index 0000000..cf6dc06
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_gives_input.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends core::num, S extends core::List<self::B::T>> extends self::A<self::B::T> {
+  constructor •([self::B::T x = null]) → void
+    : super self::A::•() {}
+}
+static method main() → dynamic {
+  self::B<core::num, core::List<core::num>> x;
+  self::B<core::int, core::List<core::int>> y = new self::B::•<core::int, core::List<core::int>>(3);
+  self::A<core::int> z = new self::B::•<core::int, core::List<core::int>>();
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.direct.transformed.expect
new file mode 100644
index 0000000..b7dd39e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Comparable<self::B::T>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic y = new self::B::•<dynamic>();
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect
new file mode 100644
index 0000000..c3b6891
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Comparable<self::B::T>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::B<core::Comparable<dynamic>> y = new self::B::•<core::Comparable<dynamic>>();
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/instantiate_to_bound/inference_super_bounded_rejected.dart:11:13: Error: Can't use a super-bounded type for instance creation. Got '#lib1::B<dart.core::Comparable<dynamic>>'.
+var y = new B();
+            ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.direct.transformed.expect
new file mode 100644
index 0000000..f455106
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(self::A<dynamic> a) → dynamic
+    return null;
+  method bar() → self::A<dynamic>
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.strong.transformed.expect
new file mode 100644
index 0000000..8b8b879
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/instantiated_in_outline.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo(self::A<core::num> a) → dynamic
+    return null;
+  method bar() → self::A<core::num>
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.direct.transformed.expect
new file mode 100644
index 0000000..4d4eb3a
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic a = <self::A<dynamic>>[];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.strong.transformed.expect
new file mode 100644
index 0000000..e031824
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<self::A<core::num>> a = <self::A<core::num>>[];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.direct.transformed.expect
new file mode 100644
index 0000000..7c0008d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<S extends core::Object> extends core::Object {
+  final field core::List<self::A<self::B::S>> foo = <self::A<self::B::S>>[];
+  final field core::List<self::A<core::num>> bar = <self::A<core::num>>[];
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.strong.transformed.expect
new file mode 100644
index 0000000..7c0008d
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_list_with_generic_argument.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<S extends core::Object> extends core::Object {
+  final field core::List<self::A<self::B::S>> foo = <self::A<self::B::S>>[];
+  final field core::List<self::A<core::num>> bar = <self::A<core::num>>[];
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.direct.transformed.expect
new file mode 100644
index 0000000..cde27c3
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic a = <self::A<dynamic>, self::A<dynamic>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.strong.transformed.expect
new file mode 100644
index 0000000..945d678
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/literal_map.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::Map<self::A<core::num>, self::A<core::num>> a = <self::A<core::num>, self::A<core::num>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.direct.transformed.expect
new file mode 100644
index 0000000..9ecef65
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.direct.transformed.expect
@@ -0,0 +1,62 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends self::A<self::D::X>, Y extends self::A<self::D::Y>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<W extends self::B<self::E::W, self::E::X>, X extends self::C<self::E::W, self::E::X>, Y extends self::B<self::E::Y, self::E::Z>, Z extends self::C<self::E::Y, self::E::Z>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F<V extends core::num, W extends self::B<self::F::W, self::F::X>, X extends self::C<self::F::W, self::F::X>, Y extends self::B<self::F::W, self::F::X>, Z extends self::C<self::F::Y, self::F::Z>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class G<V extends core::num, W extends self::B<self::G::V, self::G::X>, X extends self::C<self::G::W, self::G::V>, Y extends self::B<self::G::W, self::G::X>, Z extends self::C<self::G::Y, self::G::Z>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class H<S extends self::A<self::H::S>, T extends self::B<self::H::T, self::H::U>, U extends self::C<self::H::T, self::H::U>, V extends self::A<self::H::V>, W extends self::H::S, X extends self::H::T, Y extends self::H::U, Z extends self::H::V> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class I<T extends self::I::U, U extends self::I::Y, V extends (self::I::W) → dynamic, W extends (self::I::X) → dynamic, X extends (self::I::V) → dynamic, Y extends self::I::Z, Z extends self::I::T> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class J<S extends (self::J::U) → self::J::T, T extends (self::J::S) → self::J::U, U extends (self::J::T) → self::J::S, V extends self::J::W, W extends self::J::X, X extends (self::J::V) → self::J::Y, Y extends self::J::Z, Z extends self::J::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::D<dynamic, dynamic> d;
+static field self::E<dynamic, dynamic, dynamic, dynamic> e;
+static field self::F<dynamic, dynamic, dynamic, dynamic, dynamic> f;
+static field self::G<dynamic, dynamic, dynamic, dynamic, dynamic> g;
+static field self::H<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic> h;
+static field self::I<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic> i;
+static field self::J<dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic, dynamic> j;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.transformed.expect
new file mode 100644
index 0000000..b890460
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/multiple_strongly_connected.dart.strong.transformed.expect
@@ -0,0 +1,62 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D<X extends self::A<self::D::X>, Y extends self::A<self::D::Y>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<W extends self::B<self::E::W, self::E::X>, X extends self::C<self::E::W, self::E::X>, Y extends self::B<self::E::Y, self::E::Z>, Z extends self::C<self::E::Y, self::E::Z>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class F<V extends core::num, W extends self::B<self::F::W, self::F::X>, X extends self::C<self::F::W, self::F::X>, Y extends self::B<self::F::W, self::F::X>, Z extends self::C<self::F::Y, self::F::Z>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class G<V extends core::num, W extends self::B<self::G::V, self::G::X>, X extends self::C<self::G::W, self::G::V>, Y extends self::B<self::G::W, self::G::X>, Z extends self::C<self::G::Y, self::G::Z>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class H<S extends self::A<self::H::S>, T extends self::B<self::H::T, self::H::U>, U extends self::C<self::H::T, self::H::U>, V extends self::A<self::H::V>, W extends self::H::S, X extends self::H::T, Y extends self::H::U, Z extends self::H::V> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class I<T extends self::I::U, U extends self::I::Y, V extends (self::I::W) → dynamic, W extends (self::I::X) → dynamic, X extends (self::I::V) → dynamic, Y extends self::I::Z, Z extends self::I::T> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class J<S extends (self::J::U) → self::J::T, T extends (self::J::S) → self::J::U, U extends (self::J::T) → self::J::S, V extends self::J::W, W extends self::J::X, X extends (self::J::V) → self::J::Y, Y extends self::J::Z, Z extends self::J::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::D<self::A<dynamic>, self::A<dynamic>> d;
+static field self::E<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>, self::B<dynamic, dynamic>, self::C<dynamic, dynamic>> e;
+static field self::F<core::num, self::B<dynamic, dynamic>, self::C<dynamic, dynamic>, self::B<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>>, self::C<self::B<self::B<dynamic, dynamic>, self::C<dynamic, dynamic>>, dynamic>> f;
+static field self::G<core::num, self::B<core::num, dynamic>, self::C<dynamic, core::num>, self::B<self::B<core::num, dynamic>, self::C<dynamic, core::num>>, self::C<self::B<self::B<core::num, dynamic>, self::C<dynamic, core::num>>, dynamic>> g;
+static field self::H<self::A<dynamic>, self::B<dynamic, dynamic>, self::C<dynamic, dynamic>, self::A<dynamic>, self::A<dynamic>, self::B<dynamic, dynamic>, self::C<dynamic, dynamic>, self::A<dynamic>> h;
+static field self::I<dynamic, dynamic, (core::Null) → dynamic, (core::Null) → dynamic, (core::Null) → dynamic, dynamic, dynamic> i;
+static field self::J<(core::Null) → dynamic, (core::Null) → dynamic, (core::Null) → dynamic, dynamic, dynamic, (core::Null) → dynamic, dynamic, dynamic> j;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.direct.transformed.expect
new file mode 100644
index 0000000..74147c8
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.direct.transformed.expect
@@ -0,0 +1,64 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C1<X extends (self::C1::Y) → self::C1::X, Y extends (self::C1::Y) → self::C1::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C2<X extends (self::C2::Y) → self::C2::X, Y extends (self::C2::X) → self::C2::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C3<X extends (self::C3::X, self::C3::Y) → self::C3::X, Y extends (self::C3::X, self::C3::Y) → self::C3::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C4<X extends (self::C4::X, self::C4::Y) → self::C4::X, Y extends (self::C4::X, self::C4::Y) → self::C4::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D1<X extends self::B<self::D1::X, self::D1::Y>, Y extends (self::D1::Y) → self::D1::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D2<X extends self::B<self::D2::X, self::D2::Y>, Y extends (self::D2::X) → self::D2::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D3<X extends self::B<self::D3::X, self::D3::Y>, Y extends (self::D3::X, self::D3::Y) → self::D3::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D4<X extends self::B<self::D4::X, self::D4::Y>, Y extends (self::D4::X, self::D4::Y) → self::D4::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends (self::E::X) → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C1<dynamic, dynamic> c1;
+static field self::C2<dynamic, dynamic> c2;
+static field self::C3<dynamic, dynamic> c3;
+static field self::C4<dynamic, dynamic> c4;
+static field self::D1<dynamic, dynamic> d1;
+static field self::D2<dynamic, dynamic> d2;
+static field self::D3<dynamic, dynamic> d3;
+static field self::D4<dynamic, dynamic> d4;
+static field self::E<dynamic> e;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.strong.transformed.expect
new file mode 100644
index 0000000..77802e7
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence.dart.strong.transformed.expect
@@ -0,0 +1,64 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C1<X extends (self::C1::Y) → self::C1::X, Y extends (self::C1::Y) → self::C1::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C2<X extends (self::C2::Y) → self::C2::X, Y extends (self::C2::X) → self::C2::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C3<X extends (self::C3::X, self::C3::Y) → self::C3::X, Y extends (self::C3::X, self::C3::Y) → self::C3::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C4<X extends (self::C4::X, self::C4::Y) → self::C4::X, Y extends (self::C4::X, self::C4::Y) → self::C4::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D1<X extends self::B<self::D1::X, self::D1::Y>, Y extends (self::D1::Y) → self::D1::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D2<X extends self::B<self::D2::X, self::D2::Y>, Y extends (self::D2::X) → self::D2::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D3<X extends self::B<self::D3::X, self::D3::Y>, Y extends (self::D3::X, self::D3::Y) → self::D3::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D4<X extends self::B<self::D4::X, self::D4::Y>, Y extends (self::D4::X, self::D4::Y) → self::D4::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends (self::E::X) → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::C1<(core::Null) → dynamic, (core::Null) → dynamic> c1;
+static field self::C2<(core::Null) → dynamic, (core::Null) → dynamic> c2;
+static field self::C3<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic> c3;
+static field self::C4<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic> c4;
+static field self::D1<self::B<dynamic, dynamic>, (core::Null) → dynamic> d1;
+static field self::D2<self::B<dynamic, dynamic>, (core::Null) → dynamic> d2;
+static field self::D3<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic> d3;
+static field self::D4<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic> d4;
+static field self::E<(core::Null) → dynamic> e;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.direct.transformed.expect
new file mode 100644
index 0000000..ec1fdc4
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.direct.transformed.expect
@@ -0,0 +1,73 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C1<X extends (self::C1::Y) → self::C1::X, Y extends (self::C1::Y) → self::C1::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C2<X extends (self::C2::Y) → self::C2::X, Y extends (self::C2::X) → self::C2::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C3<X extends (self::C3::X, self::C3::Y) → self::C3::X, Y extends (self::C3::X, self::C3::Y) → self::C3::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C4<X extends (self::C4::X, self::C4::Y) → self::C4::X, Y extends (self::C4::X, self::C4::Y) → self::C4::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D1<X extends self::B<self::D1::X, self::D1::Y>, Y extends (self::D1::Y) → self::D1::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D2<X extends self::B<self::D2::X, self::D2::Y>, Y extends (self::D2::X) → self::D2::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D3<X extends self::B<self::D3::X, self::D3::Y>, Y extends (self::D3::X, self::D3::Y) → self::D3::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D4<X extends self::B<self::D4::X, self::D4::Y>, Y extends (self::D4::X, self::D4::Y) → self::D4::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends (self::E::X) → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field dynamic lc1 = <self::C1<dynamic, dynamic>>[];
+static field dynamic mc1 = <self::C1<dynamic, dynamic>, self::C1<dynamic, dynamic>>{};
+static field dynamic lc2 = <self::C2<dynamic, dynamic>>[];
+static field dynamic mc2 = <self::C2<dynamic, dynamic>, self::C2<dynamic, dynamic>>{};
+static field dynamic lc3 = <self::C3<dynamic, dynamic>>[];
+static field dynamic mc3 = <self::C3<dynamic, dynamic>, self::C3<dynamic, dynamic>>{};
+static field dynamic lc4 = <self::C4<dynamic, dynamic>>[];
+static field dynamic mc4 = <self::C4<dynamic, dynamic>, self::C4<dynamic, dynamic>>{};
+static field dynamic ld1 = <self::D1<dynamic, dynamic>>[];
+static field dynamic md1 = <self::D1<dynamic, dynamic>, self::D1<dynamic, dynamic>>{};
+static field dynamic ld2 = <self::D2<dynamic, dynamic>>[];
+static field dynamic md2 = <self::D2<dynamic, dynamic>, self::D2<dynamic, dynamic>>{};
+static field dynamic ld3 = <self::D3<dynamic, dynamic>>[];
+static field dynamic md3 = <self::D3<dynamic, dynamic>, self::D3<dynamic, dynamic>>{};
+static field dynamic ld4 = <self::D4<dynamic, dynamic>>[];
+static field dynamic md4 = <self::D4<dynamic, dynamic>, self::D4<dynamic, dynamic>>{};
+static field dynamic le = <self::E<dynamic>>[];
+static field dynamic me = <self::E<dynamic>, self::E<dynamic>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.strong.transformed.expect
new file mode 100644
index 0000000..8a37dd2
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/mutual_dependence_in_literals.dart.strong.transformed.expect
@@ -0,0 +1,73 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B<X extends core::Object, Y extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C1<X extends (self::C1::Y) → self::C1::X, Y extends (self::C1::Y) → self::C1::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C2<X extends (self::C2::Y) → self::C2::X, Y extends (self::C2::X) → self::C2::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C3<X extends (self::C3::X, self::C3::Y) → self::C3::X, Y extends (self::C3::X, self::C3::Y) → self::C3::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C4<X extends (self::C4::X, self::C4::Y) → self::C4::X, Y extends (self::C4::X, self::C4::Y) → self::C4::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D1<X extends self::B<self::D1::X, self::D1::Y>, Y extends (self::D1::Y) → self::D1::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D2<X extends self::B<self::D2::X, self::D2::Y>, Y extends (self::D2::X) → self::D2::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D3<X extends self::B<self::D3::X, self::D3::Y>, Y extends (self::D3::X, self::D3::Y) → self::D3::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D4<X extends self::B<self::D4::X, self::D4::Y>, Y extends (self::D4::X, self::D4::Y) → self::D4::Y> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E<X extends (self::E::X) → self::E::X> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::List<self::C1<(core::Null) → dynamic, (core::Null) → dynamic>> lc1 = <self::C1<(core::Null) → dynamic, (core::Null) → dynamic>>[];
+static field core::Map<self::C1<(core::Null) → dynamic, (core::Null) → dynamic>, self::C1<(core::Null) → dynamic, (core::Null) → dynamic>> mc1 = <self::C1<(core::Null) → dynamic, (core::Null) → dynamic>, self::C1<(core::Null) → dynamic, (core::Null) → dynamic>>{};
+static field core::List<self::C2<(core::Null) → dynamic, (core::Null) → dynamic>> lc2 = <self::C2<(core::Null) → dynamic, (core::Null) → dynamic>>[];
+static field core::Map<self::C2<(core::Null) → dynamic, (core::Null) → dynamic>, self::C2<(core::Null) → dynamic, (core::Null) → dynamic>> mc2 = <self::C2<(core::Null) → dynamic, (core::Null) → dynamic>, self::C2<(core::Null) → dynamic, (core::Null) → dynamic>>{};
+static field core::List<self::C3<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>> lc3 = <self::C3<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>>[];
+static field core::Map<self::C3<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>, self::C3<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>> mc3 = <self::C3<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>, self::C3<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>>{};
+static field core::List<self::C4<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>> lc4 = <self::C4<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>>[];
+static field core::Map<self::C4<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>, self::C4<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>> mc4 = <self::C4<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>, self::C4<(core::Null, core::Null) → dynamic, (core::Null, core::Null) → dynamic>>{};
+static field core::List<self::D1<self::B<dynamic, dynamic>, (core::Null) → dynamic>> ld1 = <self::D1<self::B<dynamic, dynamic>, (core::Null) → dynamic>>[];
+static field core::Map<self::D1<self::B<dynamic, dynamic>, (core::Null) → dynamic>, self::D1<self::B<dynamic, dynamic>, (core::Null) → dynamic>> md1 = <self::D1<self::B<dynamic, dynamic>, (core::Null) → dynamic>, self::D1<self::B<dynamic, dynamic>, (core::Null) → dynamic>>{};
+static field core::List<self::D2<self::B<dynamic, dynamic>, (core::Null) → dynamic>> ld2 = <self::D2<self::B<dynamic, dynamic>, (core::Null) → dynamic>>[];
+static field core::Map<self::D2<self::B<dynamic, dynamic>, (core::Null) → dynamic>, self::D2<self::B<dynamic, dynamic>, (core::Null) → dynamic>> md2 = <self::D2<self::B<dynamic, dynamic>, (core::Null) → dynamic>, self::D2<self::B<dynamic, dynamic>, (core::Null) → dynamic>>{};
+static field core::List<self::D3<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>> ld3 = <self::D3<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>>[];
+static field core::Map<self::D3<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>, self::D3<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>> md3 = <self::D3<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>, self::D3<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>>{};
+static field core::List<self::D4<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>> ld4 = <self::D4<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>>[];
+static field core::Map<self::D4<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>, self::D4<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>> md4 = <self::D4<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>, self::D4<self::B<dynamic, dynamic>, (core::Null, core::Null) → dynamic>>{};
+static field core::List<self::E<(core::Null) → dynamic>> le = <self::E<(core::Null) → dynamic>>[];
+static field core::Map<self::E<(core::Null) → dynamic>, self::E<(core::Null) → dynamic>> me = <self::E<(core::Null) → dynamic>, self::E<(core::Null) → dynamic>>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..bd60470
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → self::A<dynamic>
+    return null;
+  method baz() → col::DoubleLinkedQueue<dynamic>
+    return null;
+}
+static field self::A<dynamic> a;
+static field col::DoubleLinkedQueue<dynamic> c;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..bd60470
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/omitted_bound.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "dart:collection" as col;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → self::A<dynamic>
+    return null;
+  method baz() → col::DoubleLinkedQueue<dynamic>
+    return null;
+}
+static field self::A<dynamic> a;
+static field col::DoubleLinkedQueue<dynamic> c;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..bb24dfc
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends self::A<dynamic>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..99ef415
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/raw_in_bound.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::num> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B<T extends self::A<core::num>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..2f1df6b
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends self::A<self::A::T>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A<dynamic> a;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.strong.transformed.expect
new file mode 100644
index 0000000..08af2f5
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/super_bounded_type.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends self::A<self::A::T>> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field self::A<self::A<dynamic>> a;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.direct.transformed.expect
new file mode 100644
index 0000000..159c3d8
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class X<T extends self::B> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Y extends self::X<dynamic> {
+  synthetic constructor •() → void
+    : super self::X::•()
+    ;
+}
+static method main() → void {
+  exp::Expect::isTrue(new self::Y::•() is self::X<dynamic>);
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.transformed.expect
new file mode 100644
index 0000000..c261752
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/supertypes.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class X<T extends self::B> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Y extends self::X<self::B> {
+  synthetic constructor •() → void
+    : super self::X::•()
+    ;
+}
+static method main() → void {
+  exp::Expect::isTrue(new self::Y::•() is self::X<self::B>);
+}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.direct.transformed.expect
new file mode 100644
index 0000000..2e8df2e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo((dynamic) → dynamic a) → dynamic
+    return null;
+  method bar() → (dynamic) → dynamic
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.transformed.expect
new file mode 100644
index 0000000..52fa1cf
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_instantiated_in_outline.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo((core::num) → dynamic a) → dynamic
+    return null;
+  method bar() → (core::num) → dynamic
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.direct.transformed.expect
new file mode 100644
index 0000000..3e9d62e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+static field dynamic a = <(dynamic) → dynamic>[];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.transformed.expect
new file mode 100644
index 0000000..6194fc1
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+static field core::List<(core::num) → dynamic> a = <(core::num) → dynamic>[];
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.direct.transformed.expect
new file mode 100644
index 0000000..b156915
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object> = (T) → dynamic;
+class B<S extends core::Object> extends core::Object {
+  final field core::List<(self::B::S) → dynamic> foo = <(self::B::S) → dynamic>[];
+  final field core::List<(core::num) → dynamic> bar = <(core::num) → dynamic>[];
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.transformed.expect
new file mode 100644
index 0000000..e674c32
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_list_with_generic_argument.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object> = (T) → dynamic;
+class B<S extends core::Object> extends core::Object {
+  generic-contravariant final field core::List<(self::B::S) → dynamic> foo = <(self::B::S) → dynamic>[];
+  final field core::List<(core::num) → dynamic> bar = <(core::num) → dynamic>[];
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.direct.transformed.expect
new file mode 100644
index 0000000..5258ebf
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+static field dynamic a = <(dynamic) → dynamic, (dynamic) → dynamic>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.transformed.expect
new file mode 100644
index 0000000..c2e8007
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_literal_map.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+static field core::Map<(core::num) → dynamic, (core::num) → dynamic> a = <(core::num) → dynamic, (core::num) → dynamic>{};
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..f3c3c27
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object> = (T) → dynamic;
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → (dynamic) → dynamic
+    return null;
+}
+static field (dynamic) → dynamic a;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..f3c3c27
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_omitted_bound.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object> = (T) → dynamic;
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → (dynamic) → dynamic
+    return null;
+}
+static field (dynamic) → dynamic a;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.direct.transformed.expect
new file mode 100644
index 0000000..ddb4888
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+class B<T extends (dynamic) → dynamic> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.transformed.expect
new file mode 100644
index 0000000..03b6e9c
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_raw_in_bound.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::num> = (T) → dynamic;
+class B<T extends (core::num) → dynamic> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.direct.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..819253e
--- /dev/null
+++ b/pkg/front_end/testcases/instantiate_to_bound/typedef_super_bounded_type.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef A<T extends core::Object> = (T) → dynamic;
+typedef B<S extends (S) → dynamic> = (S) → dynamic;
+static field (dynamic) → dynamic b;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/invalid_assignment.dart.direct.transformed.expect b/pkg/front_end/testcases/invalid_assignment.dart.direct.transformed.expect
new file mode 100644
index 0000000..a891be4
--- /dev/null
+++ b/pkg/front_end/testcases/invalid_assignment.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int i) → core::String
+    return "";
+}
+static method test(core::int i, core::String s, self::A a) → dynamic {
+  i = 1;
+  i = s;
+  i.==(null) ? i = 1 : null;
+  i.==(null) ? i = s : null;
+  a = new self::A::•();
+  a = a.+(1);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/invalid_assignment.dart.strong.transformed.expect b/pkg/front_end/testcases/invalid_assignment.dart.strong.transformed.expect
new file mode 100644
index 0000000..a29230a
--- /dev/null
+++ b/pkg/front_end/testcases/invalid_assignment.dart.strong.transformed.expect
@@ -0,0 +1,29 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(core::int i) → core::String
+    return "";
+}
+static method test(core::int i, core::String s, self::A a) → dynamic {
+  i = 1;
+  i = let final core::String #t1 = s in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_assignment.dart:13:36: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  i = /*@error=InvalidAssignment*/ s;
+                                   ^";
+  i.{core::num::==}(null) ?{core::int} i = 1 : null;
+  i.{core::num::==}(null) ?{core::Object} i = let final core::String #t2 = s in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_assignment.dart:15:38: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::int'.
+  i ??= /*@error=InvalidAssignment*/ s;
+                                     ^" : null;
+  a = new self::A::•();
+  a = let final core::String #t3 = a.{self::A::+}(1) in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_assignment.dart:17:34: Error: A value of type 'dart.core::String' can't be assigned to a variable of type '#lib1::A'.
+Try changing the type of the left hand side, or casting the right hand side to '#lib1::A'.
+  a /*@error=InvalidAssignment*/ += 1;
+                                 ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/invalid_cast.dart.direct.transformed.expect b/pkg/front_end/testcases/invalid_cast.dart.direct.transformed.expect
new file mode 100644
index 0000000..d768d66
--- /dev/null
+++ b/pkg/front_end/testcases/invalid_cast.dart.direct.transformed.expect
@@ -0,0 +1,56 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field dynamic _redirecting# = <dynamic>[self::C::fact2];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  constructor nonFact() → void
+    : super core::Object::•()
+    ;
+  constructor nonFact2() → void
+    : this self::C::nonFact()
+    ;
+  static factory fact() → self::C
+    return null;
+  static factory fact2() → self::C
+    let dynamic #redirecting_factory = self::D::• in invalid-expression;
+  static method staticFunction(core::int i) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+static method topLevelFunction(core::int i) → void {}
+static method bad() → dynamic {
+  function localFunction(core::int i) → void {}
+  core::List<core::int> a = <core::Object>[];
+  core::Map<core::int, core::String> b = <core::Object, core::String>{};
+  core::Map<core::int, core::String> c = <core::int, core::Object>{};
+  (core::Object) → core::int d = (core::int i) → dynamic => i;
+  self::D e = self::C::fact();
+  self::D f = new self::D::•();
+  self::D g = new self::C::nonFact();
+  self::D h = new self::C::nonFact2();
+  (core::Object) → void i = self::C::staticFunction;
+  (core::Object) → void j = self::topLevelFunction;
+  (core::Object) → void k = localFunction;
+}
+static method ok() → dynamic {
+  function localFunction(core::int i) → void {}
+  core::List<core::int> a = <core::int>[];
+  core::Map<core::int, core::String> b = <core::int, core::String>{};
+  core::Map<core::int, core::String> c = <core::int, core::String>{};
+  (core::int) → core::int d = (core::int i) → dynamic => i;
+  self::D e = self::C::fact();
+  self::D f = new self::D::•();
+  self::C g = new self::C::nonFact();
+  self::C h = new self::C::nonFact2();
+  (core::int) → void i = self::C::staticFunction;
+  (core::int) → void j = self::topLevelFunction;
+  (core::int) → void k = localFunction;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/invalid_cast.dart.strong.transformed.expect b/pkg/front_end/testcases/invalid_cast.dart.strong.transformed.expect
new file mode 100644
index 0000000..1fe3674
--- /dev/null
+++ b/pkg/front_end/testcases/invalid_cast.dart.strong.transformed.expect
@@ -0,0 +1,83 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field dynamic _redirecting# = <dynamic>[self::C::fact2];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  constructor nonFact() → void
+    : super core::Object::•()
+    ;
+  constructor nonFact2() → void
+    : this self::C::nonFact()
+    ;
+  static factory fact() → self::C
+    return null;
+  static factory fact2() → self::C
+    let<BottomType> #redirecting_factory = self::D::• in invalid-expression;
+  static method staticFunction(core::int i) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+static method topLevelFunction(core::int i) → void {}
+static method bad() → dynamic {
+  function localFunction(core::int i) → void {}
+  core::List<core::int> a = let final core::List<core::Object> #t1 = <core::Object>[] in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_cast.dart:22:60: Error: The list literal type 'dart.core::List<dart.core::Object>' isn't of expected type 'dart.core::List<dart.core::int>'.
+Change the type of the list literal or the context in which it is used.
+  List<int> a = <Object> /*@error=InvalidCastLiteralList*/ [];
+                                                           ^";
+  core::Map<core::int, core::String> b = let final core::Map<core::Object, core::String> #t2 = <core::Object, core::String>{} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_cast.dart:23:74: Error: The map literal type 'dart.core::Map<dart.core::Object, dart.core::String>' isn't of expected type 'dart.core::Map<dart.core::int, dart.core::String>'.
+Change the type of the map literal or the context in which it is used.
+  Map<int, String> b = <Object, String> /*@error=InvalidCastLiteralMap*/ {};
+                                                                         ^";
+  core::Map<core::int, core::String> c = let final core::Map<core::int, core::Object> #t3 = <core::int, core::Object>{} in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_cast.dart:24:71: Error: The map literal type 'dart.core::Map<dart.core::int, dart.core::Object>' isn't of expected type 'dart.core::Map<dart.core::int, dart.core::String>'.
+Change the type of the map literal or the context in which it is used.
+  Map<int, String> c = <int, Object> /*@error=InvalidCastLiteralMap*/ {};
+                                                                      ^";
+  (core::Object) → core::int d = let final (core::int) → core::int #t4 = (core::int i) → core::int => i in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_cast.dart:25:63: Error: The function expression type '(dart.core::int) \u8594 dart.core::int' isn't of expected type '(dart.core::Object) \u8594 dart.core::int'.
+Change the type of the function expression or the context in which it is used.
+  int Function(Object) d = /*@error=InvalidCastFunctionExpr*/ (int i) => i;
+                                                              ^";
+  self::D e = self::C::fact() as{TypeError} self::D;
+  self::D f = new self::D::•() as{TypeError} self::D;
+  self::D g = let final self::C #t5 = new self::C::nonFact() in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_cast.dart:28:43: Error: The constructor returns type '#lib1::C' that isn't of expected type '#lib1::D'.
+Change the type of the object being constructed or the context in which it is used.
+  D g = new /*@error=InvalidCastNewExpr*/ C.nonFact();
+                                          ^";
+  self::D h = let final self::C #t6 = new self::C::nonFact2() in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_cast.dart:29:43: Error: The constructor returns type '#lib1::C' that isn't of expected type '#lib1::D'.
+Change the type of the object being constructed or the context in which it is used.
+  D h = new /*@error=InvalidCastNewExpr*/ C.nonFact2();
+                                          ^";
+  (core::Object) → void i = let final (core::int) → void #t7 = self::C::staticFunction in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_cast.dart:31:45: Error: The static method has type '(dart.core::int) \u8594 void' that isn't of expected type '(dart.core::Object) \u8594 void'.
+Change the type of the method or the context in which it is used.
+      C. /*@error=InvalidCastStaticMethod*/ staticFunction;
+                                            ^";
+  (core::Object) → void j = let final (core::int) → void #t8 = self::topLevelFunction in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_cast.dart:33:50: Error: The top level function has type '(dart.core::int) \u8594 void' that isn't of expected type '(dart.core::Object) \u8594 void'.
+Change the type of the function or the context in which it is used.
+      j = /*@error=InvalidCastTopLevelFunction*/ topLevelFunction;
+                                                 ^";
+  (core::Object) → void k = let final (core::int) → void #t9 = localFunction in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/invalid_cast.dart:34:65: Error: The local function has type '(dart.core::int) \u8594 void' that isn't of expected type '(dart.core::Object) \u8594 void'.
+Change the type of the function or the context in which it is used.
+  void Function(Object) k = /*@error=InvalidCastLocalFunction*/ localFunction;
+                                                                ^";
+}
+static method ok() → dynamic {
+  function localFunction(core::int i) → void {}
+  core::List<core::int> a = <core::int>[];
+  core::Map<core::int, core::String> b = <core::int, core::String>{};
+  core::Map<core::int, core::String> c = <core::int, core::String>{};
+  (core::int) → core::int d = (core::int i) → core::int => i;
+  self::D e = self::C::fact() as{TypeError} self::D;
+  self::D f = new self::D::•() as{TypeError} self::D;
+  self::C g = new self::C::nonFact();
+  self::C h = new self::C::nonFact2();
+  (core::int) → void i = self::C::staticFunction;
+  (core::int) → void j = self::topLevelFunction;
+  (core::int) → void k = localFunction;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/literals.dart.direct.transformed.expect b/pkg/front_end/testcases/literals.dart.direct.transformed.expect
new file mode 100644
index 0000000..bd49a1d
--- /dev/null
+++ b/pkg/front_end/testcases/literals.dart.direct.transformed.expect
@@ -0,0 +1,43 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method testString() → dynamic {
+  core::print("a");
+}
+static method testInt() → dynamic {
+  core::print(1);
+}
+static method testBool() → dynamic {
+  core::print(true);
+  core::print(false);
+}
+static method testDouble() → dynamic {
+  core::print(1.0);
+}
+static method testNull() → dynamic {
+  core::print(null);
+}
+static method testList() → dynamic {
+  core::print(<dynamic>[]);
+  core::print(<dynamic>["a", "b"]);
+}
+static method testMap() → dynamic {
+  core::print(<dynamic, dynamic>{});
+  core::print(<dynamic, dynamic>{"a": "b"});
+}
+static method testSymbol() → dynamic {
+  core::print(#fisk);
+  core::print(#_fisk);
+  core::print(#fisk.hest.ko);
+}
+static method main() → dynamic {
+  self::testString();
+  self::testInt();
+  self::testBool();
+  self::testDouble();
+  self::testNull();
+  self::testList();
+  self::testMap();
+  self::testSymbol();
+}
diff --git a/pkg/front_end/testcases/local_generic_function.dart.direct.transformed.expect b/pkg/front_end/testcases/local_generic_function.dart.direct.transformed.expect
new file mode 100644
index 0000000..204a1a3
--- /dev/null
+++ b/pkg/front_end/testcases/local_generic_function.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  function f<T extends core::Object>(core::List<T> l) → T
+    return l.[](0);
+  dynamic x = f.call(<dynamic>[0]);
+}
diff --git a/pkg/front_end/testcases/local_generic_function.dart.strong.transformed.expect b/pkg/front_end/testcases/local_generic_function.dart.strong.transformed.expect
new file mode 100644
index 0000000..8f00c9d
--- /dev/null
+++ b/pkg/front_end/testcases/local_generic_function.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  function f<T extends core::Object>(core::List<T> l) → T
+    return l.{core::List::[]}(0);
+  core::int x = f.call<core::int>(<core::int>[0]);
+}
diff --git a/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect b/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect
new file mode 100644
index 0000000..f5152ff
--- /dev/null
+++ b/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect
@@ -0,0 +1,33 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Constant extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class NotConstant extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo({dynamic a = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:9: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+foo({a: Constant(), b: Constant(), c: []}) {}
+        ^", dynamic b = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:24: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+foo({a: Constant(), b: Constant(), c: []}) {}
+                       ^", dynamic c = <dynamic>[]}) → dynamic {}
+static method test() → dynamic {
+  invalid-expression "pkg/front_end/testcases/magic_const.dart:18:9: Error: Not a const constructor.
+  const NotConstant();
+        ^";
+  invalid-expression "pkg/front_end/testcases/magic_const.dart:19:3: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+  Constant();
+  ^";
+  const dynamic x = const self::Constant::•();
+  invalid-expression "pkg/front_end/testcases/magic_const.dart:21:8: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+  bool.fromEnvironment(\"fisk\");
+       ^";
+  const dynamic b = const core::bool::fromEnvironment("fisk");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect b/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
new file mode 100644
index 0000000..6648bbe
--- /dev/null
+++ b/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Constant extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class NotConstant extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo({dynamic a = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:9: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+foo({a: Constant(), b: Constant(), c: []}) {}
+        ^", dynamic b = invalid-expression "pkg/front_end/testcases/magic_const.dart:15:24: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+foo({a: Constant(), b: Constant(), c: []}) {}
+                       ^", dynamic c = <dynamic>[]}) → dynamic {}
+static method test() → dynamic {
+  invalid-expression "pkg/front_end/testcases/magic_const.dart:18:9: Error: Not a const constructor.
+  const NotConstant();
+        ^";
+  invalid-expression "pkg/front_end/testcases/magic_const.dart:19:3: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+  Constant();
+  ^";
+  const self::Constant x = const self::Constant::•();
+  invalid-expression "pkg/front_end/testcases/magic_const.dart:21:8: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
+  bool.fromEnvironment(\"fisk\");
+       ^";
+  const core::bool b = const core::bool::fromEnvironment("fisk");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/map.dart.direct.transformed.expect b/pkg/front_end/testcases/map.dart.direct.transformed.expect
new file mode 100644
index 0000000..c82d4a6
--- /dev/null
+++ b/pkg/front_end/testcases/map.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print(core::Map::•<dynamic, dynamic>());
+}
diff --git a/pkg/front_end/testcases/metadata_enum.dart.direct.transformed.expect b/pkg/front_end/testcases/metadata_enum.dart.direct.transformed.expect
new file mode 100644
index 0000000..f7b63fa
--- /dev/null
+++ b/pkg/front_end/testcases/metadata_enum.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+@self::a
+class E extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::E> values = const <self::E>[self::E::E1, self::E::E2, self::E::E3];
+  static const field self::E E1 = const self::E::•(0, "E.E1");
+  static const field self::E E2 = const self::E::•(1, "E.E2");
+  static const field self::E E3 = const self::E::•(2, "E.E3");
+  const constructor •(core::int index, core::String _name) → void
+    : self::E::index = index, self::E::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::E::_name};
+}
+static const field dynamic a = null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/metadata_enum.dart.strong.transformed.expect b/pkg/front_end/testcases/metadata_enum.dart.strong.transformed.expect
new file mode 100644
index 0000000..f7b63fa
--- /dev/null
+++ b/pkg/front_end/testcases/metadata_enum.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+@self::a
+class E extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::E> values = const <self::E>[self::E::E1, self::E::E2, self::E::E3];
+  static const field self::E E1 = const self::E::•(0, "E.E1");
+  static const field self::E E2 = const self::E::•(1, "E.E2");
+  static const field self::E E3 = const self::E::•(2, "E.E3");
+  const constructor •(core::int index, core::String _name) → void
+    : self::E::index = index, self::E::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::E::_name};
+}
+static const field dynamic a = null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/metadata_named_mixin_application.dart.direct.transformed.expect b/pkg/front_end/testcases/metadata_named_mixin_application.dart.direct.transformed.expect
new file mode 100644
index 0000000..39baa2f
--- /dev/null
+++ b/pkg/front_end/testcases/metadata_named_mixin_application.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+@self::a
+class C extends self::D implements self::E {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic a = null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/metadata_named_mixin_application.dart.strong.transformed.expect b/pkg/front_end/testcases/metadata_named_mixin_application.dart.strong.transformed.expect
new file mode 100644
index 0000000..39baa2f
--- /dev/null
+++ b/pkg/front_end/testcases/metadata_named_mixin_application.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+@self::a
+class C extends self::D implements self::E {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+}
+class D extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic a = null;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/minimum_int.dart.direct.transformed.expect b/pkg/front_end/testcases/minimum_int.dart.direct.transformed.expect
new file mode 100644
index 0000000..eb7af70
--- /dev/null
+++ b/pkg/front_end/testcases/minimum_int.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic
+  return core::print(-9223372036854775808);
diff --git a/pkg/front_end/testcases/minimum_int.dart.strong.transformed.expect b/pkg/front_end/testcases/minimum_int.dart.strong.transformed.expect
new file mode 100644
index 0000000..eb7af70
--- /dev/null
+++ b/pkg/front_end/testcases/minimum_int.dart.strong.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic
+  return core::print(-9223372036854775808);
diff --git a/pkg/front_end/testcases/mixin.dart.direct.transformed.expect b/pkg/front_end/testcases/mixin.dart.direct.transformed.expect
new file mode 100644
index 0000000..572573a
--- /dev/null
+++ b/pkg/front_end/testcases/mixin.dart.direct.transformed.expect
@@ -0,0 +1,82 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _B&Object&M1 extends core::Object implements self::M1 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print("M1");
+}
+abstract class _B&Object&M1&M2 extends self::_B&Object&M1 implements self::M2 {
+  synthetic constructor •() → void
+    : super self::_B&Object&M1::•()
+    ;
+  method m() → dynamic
+    return core::print("M2");
+}
+class B extends self::_B&Object&M1&M2 {
+  constructor •(dynamic value) → void
+    : super core::Object::•()
+    ;
+}
+abstract class M1 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print("M1");
+}
+abstract class M2 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print("M2");
+}
+abstract class _C&Object&M1 extends core::Object implements self::M1 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print("M1");
+}
+abstract class _C&Object&M1&M2 extends self::_C&Object&M1 implements self::M2 {
+  synthetic constructor •() → void
+    : super self::_C&Object&M1::•()
+    ;
+  method m() → dynamic
+    return core::print("M2");
+}
+class C extends self::_C&Object&M1&M2 {
+  constructor •(dynamic value) → void
+    : super core::Object::•()
+    ;
+}
+abstract class G1<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print(self::G1::T);
+}
+abstract class _D&Object&G1<S extends core::Object> extends core::Object implements self::G1<self::_D&Object&G1::S> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print(self::_D&Object&G1::S);
+}
+class D<S extends core::Object> extends self::_D&Object&G1<self::D::S> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  new self::B::•(null).m();
+  new self::C::•(null).m();
+  new self::D::•<dynamic>().m();
+  new self::D::•<core::int>().m();
+  new self::D::•<core::List<core::int>>().m();
+}
diff --git a/pkg/front_end/testcases/mixin.dart.strong.transformed.expect b/pkg/front_end/testcases/mixin.dart.strong.transformed.expect
new file mode 100644
index 0000000..e84c17f
--- /dev/null
+++ b/pkg/front_end/testcases/mixin.dart.strong.transformed.expect
@@ -0,0 +1,82 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class _B&Object&M1 extends core::Object implements self::M1 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print("M1");
+}
+abstract class _B&Object&M1&M2 extends self::_B&Object&M1 implements self::M2 {
+  synthetic constructor •() → void
+    : super self::_B&Object&M1::•()
+    ;
+  method m() → dynamic
+    return core::print("M2");
+}
+class B extends self::_B&Object&M1&M2 {
+  constructor •(dynamic value) → void
+    : super core::Object::•()
+    ;
+}
+abstract class M1 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print("M1");
+}
+abstract class M2 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print("M2");
+}
+abstract class _C&Object&M1 extends core::Object implements self::M1 {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print("M1");
+}
+abstract class _C&Object&M1&M2 extends self::_C&Object&M1 implements self::M2 {
+  synthetic constructor •() → void
+    : super self::_C&Object&M1::•()
+    ;
+  method m() → dynamic
+    return core::print("M2");
+}
+class C extends self::_C&Object&M1&M2 {
+  constructor •(dynamic value) → void
+    : super core::Object::•()
+    ;
+}
+abstract class G1<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print(self::G1::T);
+}
+abstract class _D&Object&G1<S extends core::Object> extends core::Object implements self::G1<self::_D&Object&G1::S> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return core::print(self::_D&Object&G1::S);
+}
+class D<S extends core::Object> extends self::_D&Object&G1<self::D::S> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  new self::B::•(null).{self::M2::m}();
+  new self::C::•(null).{self::M2::m}();
+  new self::D::•<dynamic>().{self::G1::m}();
+  new self::D::•<core::int>().{self::G1::m}();
+  new self::D::•<core::List<core::int>>().{self::G1::m}();
+}
diff --git a/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.direct.transformed.expect b/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.direct.transformed.expect
index 064c86e..6424b60 100644
--- a/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.direct.transformed.expect
@@ -1,42 +1,46 @@
+library;
+import self as self;
+import "dart:core" as core;
+
 class A extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
 }
-class C<T extends mix::A> extends core::Object {
-  field mix::C::T _field = null;
+class C<T extends self::A> extends core::Object {
+  field self::C::T _field = null;
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method foo(mix::C::T x) → dynamic {
-    this.{mix::C::_field} = x;
+  method foo(self::C::T x) → dynamic {
+    this.{self::C::_field} = x;
   }
 }
-class D extends mix::C<mix::B> {
+class D extends self::C<self::B> {
   synthetic constructor •() → void
-    : super mix::C::•()
+    : super self::C::•()
     ;
 }
-abstract class _Foo&Object&C extends core::Object implements mix::C<mix::B> {
-  field mix::B _field = null;
+abstract class _Foo&Object&C extends core::Object implements self::C<self::B> {
+  field self::B _field = null;
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method foo(mix::B x) → dynamic {
-    this.{mix::C::_field} = x;
+  method foo(self::B x) → dynamic {
+    this.{self::C::_field} = x;
   }
 }
-class Foo extends mix::_Foo&Object&C {
+class Foo extends self::_Foo&Object&C {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
 }
-class B extends mix::A {
+class B extends self::A {
   synthetic constructor •() → void
-    : super mix::A::•()
+    : super self::A::•()
     ;
 }
 static method main() → dynamic {
-  dynamic foo = new mix::Foo::•();
-  foo.foo(new mix::B::•());
+  dynamic foo = new self::Foo::•();
+  foo.foo(new self::B::•());
 }
diff --git a/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.strong.transformed.expect b/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.strong.transformed.expect
index 8935444..79519a1 100644
--- a/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/mixin_inherited_setter_for_mixed_in_field.dart.strong.transformed.expect
@@ -1,45 +1,49 @@
+library;
+import self as self;
+import "dart:core" as core;
+
 class A extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
 }
-class C<T extends mix::A> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field mix::C::T _field = null;
+class C<T extends self::A> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T _field = null;
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method foo(generic-covariant-impl generic-covariant-interface mix::C::T x) → dynamic {
-    this.{mix::C::_field} = x;
+  method foo(generic-covariant-impl generic-covariant-interface self::C::T x) → dynamic {
+    this.{self::C::_field} = x;
   }
 }
-class D extends mix::C<mix::B> {
+class D extends self::C<self::B> {
   synthetic constructor •() → void
-    : super mix::C::•()
+    : super self::C::•()
     ;
-  abstract forwarding-stub method foo(generic-covariant-impl mix::B x) → dynamic;
-  abstract forwarding-stub set _field(generic-covariant-impl mix::B _) → void;
+  abstract forwarding-stub method foo(generic-covariant-impl self::B x) → dynamic;
+  abstract forwarding-stub set _field(generic-covariant-impl self::B _) → void;
 }
-abstract class _Foo&Object&C extends core::Object implements mix::C<mix::B> {
-  generic-covariant-impl field mix::B _field = null;
+abstract class _Foo&Object&C extends core::Object implements self::C<self::B> {
+  generic-covariant-impl field self::B _field = null;
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method foo(generic-covariant-impl mix::B x) → dynamic {
-    this.{mix::C::_field} = x;
+  method foo(generic-covariant-impl self::B x) → dynamic {
+    this.{self::C::_field} = x;
   }
 }
-class Foo extends mix::_Foo&Object&C {
+class Foo extends self::_Foo&Object&C {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract forwarding-stub set _field(generic-covariant-impl mix::B _) → void;
+  abstract forwarding-stub set _field(generic-covariant-impl self::B _) → void;
 }
-class B extends mix::A {
+class B extends self::A {
   synthetic constructor •() → void
-    : super mix::A::•()
+    : super self::A::•()
     ;
 }
 static method main() → dynamic {
-  mix::Foo foo = new mix::Foo::•();
-  foo.{mix::C::foo}(new mix::B::•());
+  self::Foo foo = new self::Foo::•();
+  foo.{self::C::foo}(new self::B::•());
 }
diff --git a/pkg/front_end/testcases/mixin_super_repeated.dart.direct.transformed.expect b/pkg/front_end/testcases/mixin_super_repeated.dart.direct.transformed.expect
new file mode 100644
index 0000000..1cf4d0f
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_super_repeated.dart.direct.transformed.expect
@@ -0,0 +1,58 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class M extends core::Object {
+  field dynamic m = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class N extends self::M {
+  synthetic constructor •() → void
+    : super self::M::•()
+    ;
+  set superM(dynamic value) → void {
+    super.{self::M::m} = value;
+  }
+  get superM() → dynamic
+    return super.{self::M::m};
+}
+class S extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _Named&S&M extends self::S implements self::M {
+  field dynamic m = null;
+  synthetic constructor •() → void
+    : super self::S::•()
+    ;
+}
+abstract class _Named&S&M&N extends self::_Named&S&M implements self::N {
+  synthetic constructor •() → void
+    : super self::_Named&S&M::•()
+    ;
+  set superM(dynamic value) → void {
+    super.{self::M::m} = value;
+  }
+  get superM() → dynamic
+    return super.{self::M::m};
+}
+class Named extends self::_Named&S&M&N implements self::M {
+  field dynamic m = null;
+  synthetic constructor •() → void
+    : super self::S::•()
+    ;
+}
+static method main() → dynamic {
+  self::Named named = new self::Named::•();
+  named.m = 42;
+  named.superM = 87;
+  if(!named.m.==(42)) {
+    throw "Bad mixin translation of set:superM";
+  }
+  if(!named.superM.==(87)) {
+    throw "Bad mixin translation of get:superM";
+  }
+}
diff --git a/pkg/front_end/testcases/mixin_super_repeated.dart.strong.transformed.expect b/pkg/front_end/testcases/mixin_super_repeated.dart.strong.transformed.expect
new file mode 100644
index 0000000..722cdb3
--- /dev/null
+++ b/pkg/front_end/testcases/mixin_super_repeated.dart.strong.transformed.expect
@@ -0,0 +1,58 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class M extends core::Object {
+  field dynamic m = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class N extends self::M {
+  synthetic constructor •() → void
+    : super self::M::•()
+    ;
+  set superM(dynamic value) → void {
+    super.{self::M::m} = value;
+  }
+  get superM() → dynamic
+    return super.{self::M::m};
+}
+class S extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _Named&S&M extends self::S implements self::M {
+  field dynamic m = null;
+  synthetic constructor •() → void
+    : super self::S::•()
+    ;
+}
+abstract class _Named&S&M&N extends self::_Named&S&M implements self::N {
+  synthetic constructor •() → void
+    : super self::_Named&S&M::•()
+    ;
+  set superM(dynamic value) → void {
+    super.{self::M::m} = value;
+  }
+  get superM() → dynamic
+    return super.{self::M::m};
+}
+class Named extends self::_Named&S&M&N implements self::M {
+  field dynamic m = null;
+  synthetic constructor •() → void
+    : super self::S::•()
+    ;
+}
+static method main() → dynamic {
+  self::Named named = new self::Named::•();
+  named.{self::M::m} = 42;
+  named.{self::N::superM} = 87;
+  if(!named.{self::M::m}.==(42)) {
+    throw "Bad mixin translation of set:superM";
+  }
+  if(!named.{self::N::superM}.==(87)) {
+    throw "Bad mixin translation of get:superM";
+  }
+}
diff --git a/pkg/front_end/testcases/native_as_name.dart.direct.transformed.expect b/pkg/front_end/testcases/native_as_name.dart.direct.transformed.expect
new file mode 100644
index 0000000..93e5e80
--- /dev/null
+++ b/pkg/front_end/testcases/native_as_name.dart.direct.transformed.expect
@@ -0,0 +1,45 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class W extends core::Object {
+  field core::String native;
+  constructor •() → void
+    : self::W::native = "field", super core::Object::•()
+    ;
+}
+class X extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method native() → core::String
+    return "method";
+}
+class Y1 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get native() → core::String;
+}
+class Y2 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  @core::override
+  get native() → core::String
+    return "getter";
+}
+class Z extends core::Object {
+  field core::String f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set native(core::String s) → dynamic
+    return this.{self::Z::f} = s;
+}
+static method main() → dynamic {
+  core::print(new self::W::•().native);
+  core::print(new self::X::•().native());
+  core::print(new self::Y2::•().native);
+  core::print((let final dynamic #t1 = new self::Z::•() in let final dynamic #t2 = #t1.native = "setter" in #t1).f);
+}
diff --git a/pkg/front_end/testcases/native_as_name.dart.strong.transformed.expect b/pkg/front_end/testcases/native_as_name.dart.strong.transformed.expect
new file mode 100644
index 0000000..39a0b89
--- /dev/null
+++ b/pkg/front_end/testcases/native_as_name.dart.strong.transformed.expect
@@ -0,0 +1,45 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class W extends core::Object {
+  field core::String native;
+  constructor •() → void
+    : self::W::native = "field", super core::Object::•()
+    ;
+}
+class X extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method native() → core::String
+    return "method";
+}
+class Y1 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get native() → core::String;
+}
+class Y2 extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  @core::override
+  get native() → core::String
+    return "getter";
+}
+class Z extends core::Object {
+  field core::String f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set native(core::String s) → void
+    return this.{self::Z::f} = s;
+}
+static method main() → dynamic {
+  core::print(new self::W::•().{self::W::native});
+  core::print(new self::X::•().{self::X::native}());
+  core::print(new self::Y2::•().{self::Y2::native});
+  core::print((let final self::Z #t1 = new self::Z::•() in let final core::String #t2 = #t1.{self::Z::native} = "setter" in #t1).{self::Z::f});
+}
diff --git a/pkg/front_end/testcases/null_aware.dart.direct.transformed.expect b/pkg/front_end/testcases/null_aware.dart.direct.transformed.expect
new file mode 100644
index 0000000..ddf9175
--- /dev/null
+++ b/pkg/front_end/testcases/null_aware.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field core::int field = null;
+  static field core::int staticField = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::Foo foo = new self::Foo::•();
+  let final dynamic #t1 = foo in #t1.==(null) ? null : #t1.field = 5;
+  self::Foo::staticField = 5;
+  let final dynamic #t2 = foo in #t2.field.==(null) ? #t2.field = 5 : null;
+  self::Foo::staticField.==(null) ? self::Foo::staticField = 5 : null;
+  let final dynamic #t3 = foo in #t3.==(null) ? null : #t3.field.==(null) ? #t3.field = 5 : null;
+  self::Foo::staticField.==(null) ? self::Foo::staticField = 5 : null;
+  core::int intValue = let final dynamic #t4 = foo.field in #t4.==(null) ? 6 : #t4;
+  core::num numValue = let final dynamic #t5 = foo.field in #t5.==(null) ? 4.5 : #t5;
+}
diff --git a/pkg/front_end/testcases/operators.dart.direct.transformed.expect b/pkg/front_end/testcases/operators.dart.direct.transformed.expect
new file mode 100644
index 0000000..1997580
--- /dev/null
+++ b/pkg/front_end/testcases/operators.dart.direct.transformed.expect
@@ -0,0 +1,72 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Operators extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → dynamic
+    return null;
+  operator &(dynamic other) → dynamic
+    return null;
+  operator ~() → dynamic
+    return null;
+  operator |(dynamic other) → dynamic
+    return null;
+  operator ^(dynamic other) → dynamic
+    return null;
+  operator /(dynamic other) → dynamic
+    return null;
+  operator ==(dynamic other) → dynamic
+    return null;
+  operator >(dynamic other) → dynamic
+    return null;
+  operator >=(dynamic other) → dynamic
+    return null;
+  operator [](dynamic index) → dynamic
+    return null;
+  operator []=(dynamic index, dynamic value) → void {}
+  operator <<(dynamic other) → dynamic
+    return null;
+  operator <(dynamic other) → dynamic
+    return null;
+  operator <=(dynamic other) → dynamic
+    return null;
+  operator *(dynamic other) → dynamic
+    return null;
+  operator %(dynamic other) → dynamic
+    return null;
+  operator >>(dynamic other) → dynamic
+    return null;
+  operator -(dynamic other) → dynamic
+    return null;
+  operator ~/(dynamic other) → dynamic
+    return null;
+  operator unary-() → dynamic
+    return null;
+}
+static method main(dynamic arguments) → dynamic {
+  dynamic a = new self::Operators::•();
+  dynamic b = new self::Operators::•();
+  a.+(b);
+  a.&(b);
+  a.~();
+  a.|(b);
+  a.^(b);
+  a./(b);
+  a.==(b);
+  a.>(b);
+  a.>=(b);
+  a.[](0);
+  a.[]=(0, b);
+  a.<<(b);
+  a.<(b);
+  a.<=(b);
+  a.*(b);
+  a.%(b);
+  a.>>(b);
+  a.-(b);
+  a.~/(b);
+  a.unary-();
+}
diff --git a/pkg/front_end/testcases/override.dart.direct.transformed.expect b/pkg/front_end/testcases/override.dart.direct.transformed.expect
new file mode 100644
index 0000000..f491b61
--- /dev/null
+++ b/pkg/front_end/testcases/override.dart.direct.transformed.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends self::Foo {
+  synthetic constructor •() → void
+    : super self::Foo::•()
+    ;
+}
+class Base extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method method() → self::Foo {
+    return new self::Foo::•();
+  }
+}
+class Sub extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method method() → self::Foo {
+    return new self::Bar::•();
+  }
+}
+static method main(core::List<core::String> args) → dynamic {
+  dynamic object = args.length.==(0) ? new self::Base::•() : new self::Sub::•();
+  dynamic a = object.method();
+  core::print(a);
+}
diff --git a/pkg/front_end/testcases/override.dart.strong.transformed.expect b/pkg/front_end/testcases/override.dart.strong.transformed.expect
new file mode 100644
index 0000000..da081a5
--- /dev/null
+++ b/pkg/front_end/testcases/override.dart.strong.transformed.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends self::Foo {
+  synthetic constructor •() → void
+    : super self::Foo::•()
+    ;
+}
+class Base extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method method() → self::Foo {
+    return new self::Foo::•();
+  }
+}
+class Sub extends self::Base {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method method() → self::Foo {
+    return new self::Bar::•();
+  }
+}
+static method main(core::List<core::String> args) → dynamic {
+  self::Base object = args.{core::List::length}.{core::num::==}(0) ?{self::Base} new self::Base::•() : new self::Sub::•();
+  self::Foo a = object.{self::Base::method}();
+  core::print(a);
+}
diff --git a/pkg/front_end/testcases/override_check_accessor_after_inference.dart.direct.transformed.expect b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.direct.transformed.expect
new file mode 100644
index 0000000..929fb02
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_accessor_after_inference.dart.direct.transformed.expect
@@ -0,0 +1,47 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(self::A value) → void {}
+  get y() → self::B
+    return null;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set x(dynamic value) → void {}
+  get y() → dynamic
+    return null;
+}
+class E extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  set x(self::A value) → void {}
+  get y() → self::B
+    return null;
+}
+class F extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  set x(self::B value) → void {}
+  get y() → self::A
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_accessor_basic.dart.direct.transformed.expect b/pkg/front_end/testcases/override_check_accessor_basic.dart.direct.transformed.expect
new file mode 100644
index 0000000..28beda4
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_accessor_basic.dart.direct.transformed.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(self::A value) → void {}
+  get y() → self::A
+    return null;
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set x(core::Object value) → void {}
+  get y() → self::B
+    return null;
+}
+class E extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set x(self::B value) → void {}
+  get y() → core::Object
+    return null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.direct.transformed.expect b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.direct.transformed.expect
new file mode 100644
index 0000000..66aef63
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_accessor_with_covariant_modifier.dart.direct.transformed.expect
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x1(covariant self::A value) → void {}
+  set x2(self::A value) → void {}
+  set x3(covariant self::A value) → void {}
+  set x4(self::A value) → void {}
+  set x5(covariant self::A value) → void {}
+  set x6(covariant self::B value) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set x1(self::B value) → void {}
+  set x2(covariant self::B value) → void {}
+  set x3(covariant self::B value) → void {}
+  set x4(self::B value) → void {}
+  set x5(covariant core::String value) → void {}
+  set x6(covariant self::A value) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_after_inference.dart.direct.transformed.expect b/pkg/front_end/testcases/override_check_after_inference.dart.direct.transformed.expect
new file mode 100644
index 0000000..aecb023
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_after_inference.dart.direct.transformed.expect
@@ -0,0 +1,39 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(self::A x) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f(dynamic x) → void {}
+}
+class E extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method f(self::A x) → void {}
+}
+class F extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method f(self::B x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_basic.dart.direct.transformed.expect b/pkg/front_end/testcases/override_check_basic.dart.direct.transformed.expect
new file mode 100644
index 0000000..cb5a353
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_basic.dart.direct.transformed.expect
@@ -0,0 +1,42 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1(self::A x) → void {}
+  method f2([self::A x = null]) → void {}
+  method f3({self::A x = null}) → void {}
+  method f4() → self::A {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f1(core::Object x) → void {}
+  method f2([core::Object x = null]) → void {}
+  method f3({core::Object x = null}) → void {}
+  method f4() → self::B {}
+}
+class E extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f1(self::B x) → void {}
+  method f2([self::B x = null]) → void {}
+  method f3({self::B x = null}) → void {}
+  method f4() → core::Object {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_two_substitutions.dart.direct.transformed.expect b/pkg/front_end/testcases/override_check_two_substitutions.dart.direct.transformed.expect
new file mode 100644
index 0000000..0273119
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_two_substitutions.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends core::Object>(core::Map<self::A::T, self::A::f::U> m) → void {}
+}
+class B extends self::A<core::String> {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  method f<V extends core::Object>(core::Map<core::String, self::B::f::V> m) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_two_substitutions.dart.strong.transformed.expect b/pkg/front_end/testcases/override_check_two_substitutions.dart.strong.transformed.expect
new file mode 100644
index 0000000..5871307
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_two_substitutions.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends core::Object>(generic-covariant-impl generic-covariant-interface core::Map<self::A::T, self::A::f::U> m) → void {}
+}
+class B extends self::A<core::String> {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  method f<V extends core::Object>(generic-covariant-impl core::Map<core::String, self::B::f::V> m) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.direct.transformed.expect b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.direct.transformed.expect
new file mode 100644
index 0000000..fe85b88
--- /dev/null
+++ b/pkg/front_end/testcases/override_check_with_covariant_modifier.dart.direct.transformed.expect
@@ -0,0 +1,37 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1(covariant self::A x) → void {}
+  method f2(self::A x) → void {}
+  method f3(covariant self::A x) → void {}
+  method f4(self::A x) → void {}
+  method f5(covariant self::A x) → void {}
+  method f6(covariant self::B x) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f1(self::B x) → void {}
+  method f2(covariant self::B x) → void {}
+  method f3(covariant self::B x) → void {}
+  method f4(self::B x) → void {}
+  method f5(covariant core::String x) → void {}
+  method f6(covariant self::A x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/platform.dart.direct.transformed.expect b/pkg/front_end/testcases/platform.dart.direct.transformed.expect
new file mode 100644
index 0000000..bef6d48
--- /dev/null
+++ b/pkg/front_end/testcases/platform.dart.direct.transformed.expect
@@ -0,0 +1,4 @@
+library;
+import self as self;
+
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/prefer_baseclass.dart.direct.transformed.expect b/pkg/front_end/testcases/prefer_baseclass.dart.direct.transformed.expect
new file mode 100644
index 0000000..a31ae2c
--- /dev/null
+++ b/pkg/front_end/testcases/prefer_baseclass.dart.direct.transformed.expect
@@ -0,0 +1,42 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class AB1 extends self::A implements self::B {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class AB2 extends self::A implements self::B {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class BA1 extends self::B implements self::A {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+class BA2 extends self::B implements self::A {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method takeSubclassOfA(dynamic obj) → dynamic {}
+static method takeSubclassOfB(dynamic obj) → dynamic {}
+static method main() → dynamic {
+  self::takeSubclassOfA(new self::AB1::•());
+  self::takeSubclassOfA(new self::AB2::•());
+  self::takeSubclassOfB(new self::BA1::•());
+  self::takeSubclassOfB(new self::BA2::•());
+}
diff --git a/pkg/front_end/testcases/qualified.dart.direct.transformed.expect b/pkg/front_end/testcases/qualified.dart.direct.transformed.expect
new file mode 100644
index 0000000..6849bb6
--- /dev/null
+++ b/pkg/front_end/testcases/qualified.dart.direct.transformed.expect
@@ -0,0 +1,46 @@
+library test.qualified.main;
+import self as self;
+import "dart:core" as core;
+import "./qualified_lib.dart" as lib;
+
+class Bad extends core::Object {
+  method method() → invalid-type {}
+  static factory WrongName() → self::Bad {}
+}
+abstract class _WithMixin&Supertype&Mixin extends lib::Supertype implements lib::Mixin {
+  synthetic constructor •() → void
+    : super lib::Supertype::•()
+    ;
+  method /* from org-dartlang-testcase:///qualified_lib.dart */ foo() → dynamic {
+    core::print("I'm Mixin.foo");
+  }
+}
+class WithMixin extends self::_WithMixin&Supertype&Mixin {
+  synthetic constructor •() → void
+    : super lib::Supertype::•()
+    ;
+}
+class C<T extends core::Object> extends core::Object { // from org-dartlang-testcase:///qualified_part.dart
+  static field dynamic _redirecting# = <dynamic>[self::C::b];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  constructor a() → void
+    : super core::Object::•()
+    ;
+  static factory b<T extends core::Object>() → self::C<self::C::b::T>
+    let dynamic #redirecting_factory = lib::C::b in let self::C::b::T #typeArg0 = null in invalid-expression;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/qualified.dart:11:7: Error: The type 'lib.Missing' can't be used as supertype.
+class Bad extends lib.Missing {
+      ^"]/* from null */;
+static method main() → dynamic {
+  new self::C::•<core::String>();
+  new self::C::a<core::String>();
+  new lib::C::a<core::String>();
+  new lib::C::•<core::String>();
+  new lib::C::a<core::String>();
+  new lib::C::a<core::String>();
+  new self::WithMixin::•().supertypeMethod();
+  new self::WithMixin::•().foo();
+}
diff --git a/pkg/front_end/testcases/qualified.dart.strong.transformed.expect b/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
new file mode 100644
index 0000000..5a41492
--- /dev/null
+++ b/pkg/front_end/testcases/qualified.dart.strong.transformed.expect
@@ -0,0 +1,48 @@
+library test.qualified.main;
+import self as self;
+import "dart:core" as core;
+import "./qualified_lib.dart" as lib;
+
+class Bad extends core::Object {
+  method method() → invalid-type {}
+  static factory WrongName() → self::Bad {}
+}
+abstract class _WithMixin&Supertype&Mixin extends lib::Supertype implements lib::Mixin {
+  synthetic constructor •() → void
+    : super lib::Supertype::•()
+    ;
+  method /* from org-dartlang-testcase:///qualified_lib.dart */ foo() → dynamic {
+    core::print("I'm Mixin.foo");
+  }
+}
+class WithMixin extends self::_WithMixin&Supertype&Mixin {
+  synthetic constructor •() → void
+    : super lib::Supertype::•()
+    ;
+}
+class C<T extends core::Object> extends core::Object { // from org-dartlang-testcase:///qualified_part.dart
+  static field dynamic _redirecting# = <dynamic>[self::C::b];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  constructor a() → void
+    : super core::Object::•()
+    ;
+  static factory b<T extends core::Object>() → self::C<self::C::b::T>
+    let <T extends core::Object>() → lib::C<lib::C::b::T> #redirecting_factory = lib::C::b in let self::C::b::T #typeArg0 = null in invalid-expression;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/qualified.dart:12:3: Error: Type 'lib.Missing' not found.
+  lib.Missing method() {}
+  ^", "pkg/front_end/testcases/qualified.dart:11:7: Error: The type 'lib.Missing' can't be used as supertype.
+class Bad extends lib.Missing {
+      ^", "pkg/front_end/testcases/qualified.dart: Error: Couldn't find constructor 'WrongName'."]/* from null */;
+static method main() → dynamic {
+  new self::C::•<core::String>();
+  new self::C::a<core::String>();
+  new lib::C::a<core::String>();
+  new lib::C::•<core::String>();
+  new lib::C::a<core::String>();
+  new lib::C::a<core::String>();
+  new self::WithMixin::•().{lib::Supertype::supertypeMethod}();
+  new self::WithMixin::•().{lib::Mixin::foo}();
+}
diff --git a/pkg/front_end/testcases/rasta/cascades.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/cascades.dart.direct.transformed.expect
new file mode 100644
index 0000000..3e0316e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/cascades.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method add(dynamic x) → dynamic
+    return x;
+}
+static method main() → dynamic {
+  dynamic a = new self::A::•();
+  function f(dynamic x) → dynamic
+    return x;
+  let final dynamic #t1 = a in let final dynamic #t2 = #t1.add(f).call("WHAT") in #t1;
+}
diff --git a/pkg/front_end/testcases/rasta/duplicated_mixin.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.direct.transformed.expect
new file mode 100644
index 0000000..f2ec868
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Mixin extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&Object&Mixin extends core::Object implements self::Mixin {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&Object&Mixin&Mixin extends self::_A&Object&Mixin implements self::Mixin {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super self::_A&Object&Mixin::•()
+    ;
+}
+class A extends self::_A&Object&Mixin&Mixin {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/rasta/duplicated_mixin.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.strong.transformed.expect
new file mode 100644
index 0000000..f2ec868
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/duplicated_mixin.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Mixin extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&Object&Mixin extends core::Object implements self::Mixin {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _A&Object&Mixin&Mixin extends self::_A&Object&Mixin implements self::Mixin {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super self::_A&Object&Mixin::•()
+    ;
+}
+class A extends self::_A&Object&Mixin&Mixin {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
diff --git a/pkg/front_end/testcases/rasta/enum.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/enum.dart.direct.transformed.expect
new file mode 100644
index 0000000..804a5a2
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/enum.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  final field core::int index;
+  final field core::String _name;
+  static const field core::List<self::Foo> values = const <self::Foo>[self::Foo::ec1, self::Foo::ec2];
+  static const field self::Foo ec1 = const self::Foo::•(0, "Foo.ec1");
+  static const field self::Foo ec2 = const self::Foo::•(1, "Foo.ec2");
+  const constructor •(core::int index, core::String _name) → void
+    : self::Foo::index = index, self::Foo::_name = _name, super core::Object::•()
+    ;
+  method toString() → core::String
+    return this.{=self::Foo::_name};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/export.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/export.dart.direct.transformed.expect
new file mode 100644
index 0000000..07bcd0f
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/export.dart.direct.transformed.expect
@@ -0,0 +1,4 @@
+library export;
+import self as self;
+import "./foo.dart" as foo;
+additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect
new file mode 100644
index 0000000..07bcd0f
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/export.dart.strong.transformed.expect
@@ -0,0 +1,4 @@
+library export;
+import self as self;
+import "./foo.dart" as foo;
+additionalExports = (foo::foo)
diff --git a/pkg/front_end/testcases/rasta/foo.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/foo.dart.direct.transformed.expect
new file mode 100644
index 0000000..5f90b5a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/foo.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library foo;
+import self as self;
+import "dart:core" as core;
+
+static method foo() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/foo.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/foo.dart.strong.transformed.expect
new file mode 100644
index 0000000..5f90b5a
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/foo.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library foo;
+import self as self;
+import "dart:core" as core;
+
+static method foo() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/hello.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/hello.dart.direct.transformed.expect
new file mode 100644
index 0000000..fea7b39
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/hello.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print("Hello, World!");
+}
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/import_export.dart.direct.transformed.expect
new file mode 100644
index 0000000..64dfcdc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/import_export.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "./foo.dart" as foo;
+
+static method main() → dynamic {
+  foo::foo();
+}
diff --git a/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect
new file mode 100644
index 0000000..64dfcdc
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/import_export.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "./foo.dart" as foo;
+
+static method main() → dynamic {
+  foo::foo();
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000002.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000002.dart.direct.transformed.expect
new file mode 100644
index 0000000..5ee9b9b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000002.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+import "dart:typed_data" as typ;
+
+class Foo extends core::Object {
+  final field dynamic value;
+  constructor •(dynamic value) → void
+    : self::Foo::value = value, super core::Object::•() {}
+  static factory fac(dynamic value) → self::Foo {
+    return new self::Foo::•(value);
+  }
+}
+static field dynamic list = <dynamic>[1, 2, 3];
+static method main() → dynamic {
+  exp::Expect::isTrue(typ::Uint8List::fromList(self::list).[](1).==(2));
+  exp::Expect::isTrue(self::Foo::fac(10).value.==(10));
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000004.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000004.dart.direct.transformed.expect
new file mode 100644
index 0000000..4c7bdc0
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000004.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "package:expect/expect.dart" as exp;
+
+static field dynamic global;
+static method fact4() → dynamic {
+  dynamic f = 1;
+  for (dynamic n in <dynamic>[1, 2, 3, 4]) {
+    f = f.*(n);
+  }
+  return f;
+}
+static method fact5() → dynamic {
+  dynamic f = 1;
+  dynamic n;
+  for (final dynamic #t1 in <dynamic>[1, 2, 3, 4, 5]) {
+    n = #t1;
+    f = f.*(n);
+  }
+  return f;
+}
+static method fact6() → dynamic {
+  dynamic f = 1;
+  for (final dynamic #t2 in <dynamic>[1, 2, 3, 4, 5, 6]) {
+    self::global = #t2;
+    f = f.*(self::global);
+  }
+  return f;
+}
+static method main() → dynamic {
+  exp::Expect::isTrue(self::fact4().==(24));
+  exp::Expect::isTrue(self::fact5().==(120));
+  exp::Expect::isTrue(self::fact6().==(720));
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000006.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000006.dart.direct.transformed.expect
new file mode 100644
index 0000000..b8b4a93
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000006.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static field dynamic list = <dynamic>[1, 2, 3];
+static method main() → dynamic {
+  self::list.add(1);
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000007.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000007.dart.direct.transformed.expect
new file mode 100644
index 0000000..4d03387
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000007.dart.direct.transformed.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Mixin extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return core::print("foo");
+}
+abstract class _Sub&Base&Mixin extends self::Base implements self::Mixin {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method foo() → dynamic
+    return core::print("foo");
+}
+class Sub extends self::_Sub&Base&Mixin {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method main() → dynamic {
+  new self::Sub::•().foo();
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000007.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000007.dart.strong.transformed.expect
new file mode 100644
index 0000000..c12cde2
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000007.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Base extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Mixin extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return core::print("foo");
+}
+abstract class _Sub&Base&Mixin extends self::Base implements self::Mixin {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+  method foo() → dynamic
+    return core::print("foo");
+}
+class Sub extends self::_Sub&Base&Mixin {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method main() → dynamic {
+  new self::Sub::•().{self::Mixin::foo}();
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000008.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000008.dart.direct.transformed.expect
new file mode 100644
index 0000000..034eb0d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000008.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  final field dynamic x;
+  constructor •(dynamic x) → void
+    : self::C::x = x, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  new self::C::•(42);
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000011.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000011.dart.direct.transformed.expect
new file mode 100644
index 0000000..aa88a42
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000011.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  try {
+    core::print(42);
+  }
+  finally {
+    core::print(87);
+  }
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000012.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000012.dart.direct.transformed.expect
new file mode 100644
index 0000000..8acc697
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000012.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  method m() → dynamic {
+    super.{self::A::field} = 42;
+  }
+}
+static method main() → dynamic {
+  new self::B::•().m();
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000025.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000025.dart.direct.transformed.expect
new file mode 100644
index 0000000..5fabc15
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000025.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static get x() → dynamic
+  return 42;
+static set x(dynamic val) → dynamic {}
+static method main() → dynamic {
+  core::print(self::x);
+  core::print(self::x = 87);
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000026.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000026.dart.direct.transformed.expect
new file mode 100644
index 0000000..b7a10584
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000026.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic a = null;
+  field dynamic b = 0;
+  field dynamic c = 1.+(2);
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object {
+  field dynamic a = null;
+  field dynamic b = 1;
+  field dynamic c = 2.-(3);
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  new self::C::•();
+  new self::D::•();
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000033.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000033.dart.direct.transformed.expect
new file mode 100644
index 0000000..0f7997f
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000033.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+@invalid-expression "pkg/front_end/testcases/rasta/issue_000033.dart:5:2: Error: Method not found: 'JS'.
+@JS()
+ ^"
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/issue_000048.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000048.dart.direct.transformed.expect
new file mode 100644
index 0000000..5b6fd06
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000048.dart.direct.transformed.expect
@@ -0,0 +1,26 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::bool v1;
+  field core::num v2;
+  constructor •(core::bool v1, core::num v2) → void
+    : self::A::v1 = v1, self::A::v2 = v2, super core::Object::•()
+    ;
+}
+class M1 extends core::Object {
+  field core::num v2 = 0;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends self::A implements self::M1 {
+  field core::num v2 = 0;
+  synthetic constructor •(core::bool v1, core::num v2) → void
+    : super self::A::•(v1, v2)
+    ;
+}
+static method main() → dynamic {
+  self::C c = new self::C::•(true, 2);
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000052.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000052.dart.direct.transformed.expect
new file mode 100644
index 0000000..d3f72c2
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000052.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  function f() → dynamic {
+    core::print("hello");
+  }
+  f.call();
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000053.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000053.dart.direct.transformed.expect
new file mode 100644
index 0000000..565ce7e
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000053.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator ==(dynamic other) → dynamic
+    return throw "x";
+  method test() → dynamic {
+    super.{core::Object::==}(null);
+  }
+}
+static method main() → dynamic {
+  new self::C::•().test();
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000067.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000067.dart.direct.transformed.expect
new file mode 100644
index 0000000..359f315
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000067.dart.direct.transformed.expect
@@ -0,0 +1,35 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+class A extends core::Object {
+  static field dynamic _redirecting# = <dynamic>[self::A::foo];
+  constructor •() → void
+    : super core::Object::•() {}
+  static factory foo() → self::A
+    let dynamic #redirecting_factory = self::C::bar in invalid-expression;
+  method m() → core::int {}
+}
+class C extends self::A {
+  static field dynamic _redirecting# = <dynamic>[self::C::bar];
+  constructor •() → void
+    : super self::A::•() {}
+  static factory bar() → self::C
+    let dynamic #redirecting_factory = self::D::• in invalid-expression;
+  method m() → core::int {
+    return 1;
+  }
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method m() → core::int {
+    return 2;
+  }
+}
+static method main() → dynamic {
+  self::A a = new self::D::•();
+  exp::Expect::equals(2, a.m());
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000068.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000068.dart.direct.transformed.expect
new file mode 100644
index 0000000..d2e5607
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000068.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+class G<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {
+  exp::Expect::isFalse(new self::G::•<self::B>() is self::G<self::C>);
+  exp::Expect::isFalse(new self::G::•<self::A>() is self::G<self::B>);
+  exp::Expect::isFalse(new self::G::•<self::A>() is self::G<self::C>);
+  exp::Expect::isFalse(new self::G::•<core::Object>() is self::G<self::B>);
+  exp::Expect::isFalse(new self::G::•<core::int>() is self::G<self::B>);
+  exp::Expect::isFalse(new self::G::•<core::int>() is self::G<core::double>);
+  exp::Expect::isFalse(new self::G::•<core::int>() is self::G<core::String>);
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000069.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000069.dart.direct.transformed.expect
new file mode 100644
index 0000000..9b3d5ea
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000069.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+
+static method main() → dynamic {
+  dynamic x;
+  dynamic i = 0;
+  while ((let final dynamic #t1 = i in let final dynamic #t2 = i = #t1.+(1) in #t1).<(5)) {
+    dynamic x = i;
+  }
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000070.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000070.dart.direct.transformed.expect
new file mode 100644
index 0000000..a80d4c3
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000070.dart.direct.transformed.expect
@@ -0,0 +1,43 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+class A<N extends core::Object, S extends core::Object, U extends core::Object> extends core::Object {
+  final field core::List<self::A::U> field;
+  constructor •(self::A::N n, self::A::S s) → void
+    : self::A::field = core::List::•<self::A::U>(), super core::Object::•() {
+    exp::Expect::isTrue(n is self::A::N);
+    exp::Expect::isTrue(s is self::A::S);
+  }
+  constructor empty() → void
+    : self::A::field = null, super core::Object::•() {}
+  const constructor c(self::A::U u, self::A::S s) → void
+    : self::A::field = const <dynamic>[null], super core::Object::•()
+    ;
+  static factory f<N extends core::Object, S extends core::Object, U extends core::Object>(self::A::f::S s) → self::A<self::A::f::N, self::A::f::S, self::A::f::U> {
+    exp::Expect::isTrue(s is self::A::f::S);
+    return new self::A::empty<dynamic, dynamic, dynamic>();
+  }
+  get getter() → core::List<self::A::U> {
+    return this.{self::A::field};
+  }
+  set setter(self::A::S s) → void {}
+}
+abstract class J<Aa extends core::Object, B extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class I<H extends core::Object, C extends core::Object, K extends core::Object> extends self::J<self::I::C, self::I::K> {
+  synthetic constructor •() → void
+    : super self::J::•()
+    ;
+}
+static method main() → dynamic {
+  new self::A::•<core::num, core::double, core::List<dynamic>>(1, 2.0);
+  self::A<dynamic, dynamic, dynamic> a = self::A::f<core::int, core::int, core::int>(1);
+  const self::A::c<core::int, core::int, core::List<dynamic>>(const <dynamic>[], 1);
+  dynamic z = a.getter;
+  a.setter = 1;
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000080.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/issue_000080.dart.direct.transformed.expect
new file mode 100644
index 0000000..ad6004d
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000080.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Mixin extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return 87;
+}
+abstract class _Foo&Object&Mixin extends core::Object implements self::Mixin {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return 87;
+}
+class Foo extends self::_Foo&Object&Mixin {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return super.{self::Mixin::foo}();
+  method bar() → dynamic
+    return super.{self::Mixin::field};
+}
+static method main() → dynamic {
+  dynamic f = new self::Foo::•();
+  f.field = 42;
+  core::print(f.bar());
+}
diff --git a/pkg/front_end/testcases/rasta/issue_000080.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/issue_000080.dart.strong.transformed.expect
new file mode 100644
index 0000000..66c8ff0
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/issue_000080.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Mixin extends core::Object {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return 87;
+}
+abstract class _Foo&Object&Mixin extends core::Object implements self::Mixin {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return 87;
+}
+class Foo extends self::_Foo&Object&Mixin {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return super.{self::Mixin::foo}();
+  method bar() → dynamic
+    return super.{self::Mixin::field};
+}
+static method main() → dynamic {
+  self::Foo f = new self::Foo::•();
+  f.{self::Mixin::field} = 42;
+  core::print(f.{self::Foo::bar}());
+}
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.direct.transformed.expect
new file mode 100644
index 0000000..c20357f
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Handle = (core::String) → dynamic;
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
+typedef Handle Handle(String command);
+               ^"]/* from null */;
+static method main() → dynamic {
+  (core::String) → dynamic h;
+}
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.direct.transformed.expect
new file mode 100644
index 0000000..f479708
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::foo();
+}
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect
new file mode 100644
index 0000000..935b4fb
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final core::Object #t1 = CheckLibraryIsLoaded(lib) in def::foo();
+}
diff --git a/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect
new file mode 100644
index 0000000..e047d82
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/static.dart.direct.transformed.expect
@@ -0,0 +1,85 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  static const field dynamic staticConstant = 42;
+  static field dynamic staticField = 42;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static method staticFunction() → dynamic {}
+  static get staticGetter() → dynamic
+    return null;
+  static set staticSetter(dynamic _) → dynamic {}
+}
+static method use(dynamic x) → dynamic {
+  if(x.==(new core::DateTime::now().millisecondsSinceEpoch))
+    throw "Shouldn't happen";
+}
+static method main() → dynamic {
+  try {
+    self::Foo::staticConstant;
+    self::use(self::Foo::staticConstant);
+    self::Foo::staticField;
+    self::use(self::Foo::staticField);
+    self::Foo::staticFunction;
+    self::use(self::Foo::staticFunction);
+    self::Foo::staticGetter;
+    self::use(self::Foo::staticGetter);
+    throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let final dynamic #t1 = self::Foo::staticConstant in let final dynamic #t2 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[#t1.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t1);
+    self::Foo::staticField = self::Foo::staticField.+(1);
+    self::use(let final dynamic #t3 = self::Foo::staticField in let final dynamic #t4 = self::Foo::staticField = #t3.+(1) in #t3);
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let final dynamic #t5 = self::Foo::staticFunction in let final dynamic #t6 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[#t5.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t5);
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let final dynamic #t7 = self::Foo::staticGetter in let final dynamic #t8 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[#t7.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t7);
+    self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1);
+    self::use(let final dynamic #t9 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in let final dynamic #t10 = self::Foo::staticSetter = #t9.+(1) in #t9);
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[self::Foo::staticConstant.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    self::Foo::staticField = self::Foo::staticField.+(1);
+    self::use(self::Foo::staticField = self::Foo::staticField.+(1));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[self::Foo::staticFunction.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[self::Foo::staticGetter.+(1)].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1);
+    self::use(self::Foo::staticSetter = (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).+(1));
+    self::Foo::staticConstant.call();
+    self::use(self::Foo::staticConstant.call());
+    self::Foo::staticField.call();
+    self::use(self::Foo::staticField.call());
+    self::Foo::staticFunction();
+    self::use(self::Foo::staticFunction());
+    self::Foo::staticGetter.call();
+    self::use(self::Foo::staticGetter.call());
+    (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).call();
+    self::use((throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).call());
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    self::Foo::staticField = 87;
+    self::use(self::Foo::staticField = 87);
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    self::use(let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+    self::Foo::staticSetter = 87;
+    self::use(self::Foo::staticSetter = 87);
+    self::Foo::staticConstant.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+    self::use(let final dynamic #t11 = self::Foo::staticConstant in #t11.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticConstant, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t11);
+    self::Foo::staticField.==(null) ? self::Foo::staticField = 87 : null;
+    self::use(let final dynamic #t12 = self::Foo::staticField in #t12.==(null) ? self::Foo::staticField = 87 : #t12);
+    self::Foo::staticFunction.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+    self::use(let final dynamic #t13 = self::Foo::staticFunction in #t13.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticFunction, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t13);
+    self::Foo::staticGetter.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : null;
+    self::use(let final dynamic #t14 = self::Foo::staticGetter in #t14.==(null) ? let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticGetter, 34, const <core::Type>[], <dynamic>[87].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) : #t14);
+    (let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).==(null) ? self::Foo::staticSetter = 87 : null;
+    self::use(let final dynamic #t15 = let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#staticSetter, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))) in #t15.==(null) ? self::Foo::staticSetter = 87 : #t15);
+  }
+  on core::NoSuchMethodError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/rasta/super_mixin.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/super_mixin.dart.direct.transformed.expect
new file mode 100644
index 0000000..8540267
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/super_mixin.dart.direct.transformed.expect
@@ -0,0 +1,112 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./mixin_library.dart" as mix;
+
+class Super<S extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return 40;
+  method f() → dynamic
+    return 3;
+}
+abstract class _C&Super&Mixin<V extends core::Object> extends self::Super<self::_C&Super&Mixin::V> implements mix::Mixin<self::_C&Super&Mixin::V> {
+  field dynamic x = mix::f()/* from org-dartlang-testcase:///mixin_library.dart */;
+  field dynamic y = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  field dynamic z = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  field self::_C&Super&Mixin::V t = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  synthetic constructor •() → void
+    : super self::Super::•()
+    ;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ foo() → dynamic
+    return super.foo().+(mix::f());
+  method /* from org-dartlang-testcase:///mixin_library.dart */ g(self::_C&Super&Mixin::V a) → self::_C&Super&Mixin::V
+    return null;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ h() → dynamic
+    return mix::V();
+  method /* from org-dartlang-testcase:///mixin_library.dart */ l() → dynamic
+    return mix::_private();
+  method /* from org-dartlang-testcase:///mixin_library.dart */ _privateMethod() → dynamic
+    return 49;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ publicMethod() → dynamic
+    return this.{mix::Mixin::_privateMethod}();
+}
+class C<V extends core::Object> extends self::_C&Super&Mixin<self::C::V> {
+  synthetic constructor •() → void
+    : super self::Super::•()
+    ;
+}
+abstract class _D&Super&Mixin extends self::Super<dynamic> implements mix::Mixin<dynamic> {
+  field dynamic x = mix::f()/* from org-dartlang-testcase:///mixin_library.dart */;
+  field dynamic y = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  field dynamic z = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  field dynamic t = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  synthetic constructor •() → void
+    : super self::Super::•()
+    ;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ foo() → dynamic
+    return super.foo().+(mix::f());
+  method /* from org-dartlang-testcase:///mixin_library.dart */ g(dynamic a) → dynamic
+    return null;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ h() → dynamic
+    return mix::V();
+  method /* from org-dartlang-testcase:///mixin_library.dart */ l() → dynamic
+    return mix::_private();
+  method /* from org-dartlang-testcase:///mixin_library.dart */ _privateMethod() → dynamic
+    return 49;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ publicMethod() → dynamic
+    return this.{mix::Mixin::_privateMethod}();
+}
+class D extends self::_D&Super&Mixin {
+  synthetic constructor •() → void
+    : super self::Super::•()
+    ;
+}
+class C2<V extends core::Object> extends self::Super<self::C2::V> implements mix::Mixin<self::C2::V> {
+  field dynamic x = mix::f()/* from org-dartlang-testcase:///mixin_library.dart */;
+  field dynamic y = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  field dynamic z = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  field self::C2::V t = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  synthetic constructor •() → void
+    : super self::Super::•()
+    ;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ foo() → dynamic
+    return super.foo().+(mix::f());
+  method /* from org-dartlang-testcase:///mixin_library.dart */ g(self::C2::V a) → self::C2::V
+    return null;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ h() → dynamic
+    return mix::V();
+  method /* from org-dartlang-testcase:///mixin_library.dart */ l() → dynamic
+    return mix::_private();
+  method /* from org-dartlang-testcase:///mixin_library.dart */ _privateMethod() → dynamic
+    return 49;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ publicMethod() → dynamic
+    return this.{mix::Mixin::_privateMethod}();
+}
+class D2 extends self::Super<dynamic> implements mix::Mixin<dynamic> {
+  field dynamic x = mix::f()/* from org-dartlang-testcase:///mixin_library.dart */;
+  field dynamic y = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  field dynamic z = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  field dynamic t = null /* from org-dartlang-testcase:///mixin_library.dart */;
+  synthetic constructor •() → void
+    : super self::Super::•()
+    ;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ foo() → dynamic
+    return super.foo().+(mix::f());
+  method /* from org-dartlang-testcase:///mixin_library.dart */ g(dynamic a) → dynamic
+    return null;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ h() → dynamic
+    return mix::V();
+  method /* from org-dartlang-testcase:///mixin_library.dart */ l() → dynamic
+    return mix::_private();
+  method /* from org-dartlang-testcase:///mixin_library.dart */ _privateMethod() → dynamic
+    return 49;
+  method /* from org-dartlang-testcase:///mixin_library.dart */ publicMethod() → dynamic
+    return this.{mix::Mixin::_privateMethod}();
+}
+static method main() → dynamic {
+  core::print(new self::C::•<dynamic>().foo());
+  core::print(new self::C2::•<dynamic>().foo());
+}
diff --git a/pkg/front_end/testcases/rasta/supports_reflection.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/supports_reflection.dart.direct.transformed.expect
new file mode 100644
index 0000000..b7bfa56
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/supports_reflection.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print(const core::bool::fromEnvironment("dart.library.mirrors"));
+}
diff --git a/pkg/front_end/testcases/rasta/supports_reflection.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/supports_reflection.dart.strong.transformed.expect
new file mode 100644
index 0000000..b7bfa56
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/supports_reflection.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print(const core::bool::fromEnvironment("dart.library.mirrors"));
+}
diff --git a/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.direct.transformed.expect
new file mode 100644
index 0000000..8c84e9b
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/switch_execution_case_t02.dart.direct.transformed.expect
@@ -0,0 +1,61 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method test(dynamic value) → dynamic {
+  dynamic result;
+  #L1:
+  switch(value) {
+    #L2:
+    case 1:
+      {
+        result = 1;
+        break #L1;
+      }
+    #L3:
+    case 2:
+      {
+        result = 2;
+        throw new core::FallThroughError::_create("org-dartlang-testcase:///switch_execution_case_t02.dart", 35);
+      }
+    #L4:
+    case 3:
+      {
+        result = 3;
+        throw new core::FallThroughError::_create("org-dartlang-testcase:///switch_execution_case_t02.dart", 36);
+      }
+    #L5:
+    default:
+      {
+        result = 4;
+      }
+  }
+  return result;
+}
+static method testEmptyCases(dynamic value) → dynamic {
+  dynamic result;
+  #L6:
+  switch(value) {
+    #L7:
+    case 1:
+    case 2:
+      {
+        result = 1;
+        throw new core::FallThroughError::_create("org-dartlang-testcase:///switch_execution_case_t02.dart", 46);
+      }
+    #L8:
+    case 3:
+    case 4:
+      {
+        result = 2;
+        break #L6;
+      }
+    #L9:
+    case 5:
+    case 6:
+    default:
+      {}
+  }
+  return result;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/rasta/switch_fall_through.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/switch_fall_through.dart.direct.transformed.expect
new file mode 100644
index 0000000..bbdd5fa
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/switch_fall_through.dart.direct.transformed.expect
@@ -0,0 +1,67 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  #L1:
+  switch(1) {
+    #L2:
+    case 1:
+      {
+        {
+          "No fall-through error needed.";
+          break #L1;
+          ;
+        }
+        throw new core::FallThroughError::_create("org-dartlang-testcase:///switch_fall_through.dart", 7);
+      }
+    #L3:
+    case 2:
+      {
+        {
+          "Fall-through error needed.";
+          if(true) {
+            break #L1;
+          }
+        }
+        throw new core::FallThroughError::_create("org-dartlang-testcase:///switch_fall_through.dart", 13);
+      }
+    #L4:
+    case 3:
+      {
+        try {
+          "No fall-through error needed.";
+        }
+        finally {
+          break #L1;
+        }
+        throw new core::FallThroughError::_create("org-dartlang-testcase:///switch_fall_through.dart", 20);
+      }
+    #L5:
+    case 4:
+      {
+        try {
+          "No fall-through error needed.";
+          break #L1;
+        }
+        finally {
+        }
+        throw new core::FallThroughError::_create("org-dartlang-testcase:///switch_fall_through.dart", 26);
+      }
+    #L6:
+    case 5:
+      {
+        try {
+          "Fall-through error needed.";
+        }
+        finally {
+        }
+        throw new core::FallThroughError::_create("org-dartlang-testcase:///switch_fall_through.dart", 31);
+      }
+    #L7:
+    case 10000:
+      {
+        "Should be last. No fall-through error, falling through allowed here.";
+      }
+  }
+}
diff --git a/pkg/front_end/testcases/rasta/this_invoke.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/this_invoke.dart.direct.transformed.expect
new file mode 100644
index 0000000..3bb5487
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/this_invoke.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m(dynamic x) → dynamic
+    return this.call(x);
+  method call(dynamic x) → dynamic
+    return 42;
+}
+static method main() → dynamic {
+  core::print(new self::C::•().m(42));
+}
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
index e48fa10..ce0e482 100644
--- a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.expect
@@ -32,6 +32,11 @@
     }
   }
 }
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected an identifier, but got '1'.
+    for (1 in x) {
+         ^", "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected an identifier, but got '1'.
+  for (1 in arguments) {
+       ^"]/* from null */;
 static method main(dynamic arguments) → dynamic {
   new self::Fisk::•();
   for (final dynamic #t6 in arguments) {
diff --git a/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
new file mode 100644
index 0000000..ce0e482
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unresolved_for_in.dart.direct.transformed.expect
@@ -0,0 +1,64 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef VoidFunction = () → void;
+class Fisk extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method it1(dynamic x) → dynamic {
+    for (final dynamic #t1 in x) {
+      this.key = #t1;
+      core::print(this.key);
+    }
+    for (final dynamic #t2 in x) {
+      let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+      core::print(self::Fisk);
+    }
+    for (final dynamic #t3 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:17:10: Error: Expected lvalue, but got Instance of 'PrefixBuilder'
+    for (collection in x) {
+         ^" in x) {
+      core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
+    }
+    for (final dynamic #t4 in x) {
+      let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], <dynamic>[#t4].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+      core::print(() → void);
+    }
+    for (final dynamic #t5 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected lvalue, but got 1
+    for (1 in x) {
+         ^" in x) {
+      core::print(this.key);
+    }
+  }
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/rasta/unresolved_for_in.dart:23:10: Error: Expected an identifier, but got '1'.
+    for (1 in x) {
+         ^", "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected an identifier, but got '1'.
+  for (1 in arguments) {
+       ^"]/* from null */;
+static method main(dynamic arguments) → dynamic {
+  new self::Fisk::•();
+  for (final dynamic #t6 in arguments) {
+    throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 34, const <core::Type>[], <dynamic>[#t6].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+  }
+  for (final dynamic #t7 in arguments) {
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#Fisk, 34, const <core::Type>[], <dynamic>[#t7].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    core::print(self::Fisk);
+  }
+  for (final dynamic #t8 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:37:8: Error: Expected lvalue, but got Instance of 'PrefixBuilder'
+  for (collection in arguments) {
+       ^" in arguments) {
+    core::print(invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart: Error: A library can't be used as an expression.");
+  }
+  for (final dynamic #t9 in arguments) {
+    let dynamic _ = null in throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#VoidFunction, 34, const <core::Type>[], <dynamic>[#t9].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+    core::print(() → void);
+  }
+  for (final dynamic #t10 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/rasta/unresolved_for_in.dart:43:8: Error: Expected lvalue, but got 1
+  for (1 in arguments) {
+       ^" in arguments) {
+    core::print(throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#key, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{}))));
+  }
+}
diff --git a/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.transformed.expect b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.transformed.expect
new file mode 100644
index 0000000..bdc26f1
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/unsupported_platform_library.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+
+static method #main() → dynamic {
+  throw "dart:html: Error: Not found: dart:html.";
+}
diff --git a/pkg/front_end/testcases/redirecting_constructor.dart.direct.transformed.expect b/pkg/front_end/testcases/redirecting_constructor.dart.direct.transformed.expect
new file mode 100644
index 0000000..e17a8f7
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_constructor.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  static field dynamic _redirecting# = <dynamic>[self::A::fisk];
+  constructor •() → void
+    : super core::Object::•()
+    ;
+  static factory fisk() → self::A
+    let dynamic #redirecting_factory = self::B::• in invalid-expression;
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {
+  new self::B::•();
+}
diff --git a/pkg/front_end/testcases/redirecting_initializer_arguments_assignable_test.dart.direct.transformed.expect b/pkg/front_end/testcases/redirecting_initializer_arguments_assignable_test.dart.direct.transformed.expect
new file mode 100644
index 0000000..ff74d26
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_initializer_arguments_assignable_test.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class X extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Foo<T extends self::X> extends core::Object {
+  field self::Foo::T x;
+  constructor fromX(self::X _init) → void
+    : this self::Foo::_internal(x: _init)
+    ;
+  constructor fromT(self::Foo::T _init) → void
+    : this self::Foo::_internal(x: _init)
+    ;
+  constructor _internal({self::Foo::T x = null}) → void
+    : self::Foo::x = x, super core::Object::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/redirecting_initializer_arguments_assignable_test.dart.strong.transformed.expect b/pkg/front_end/testcases/redirecting_initializer_arguments_assignable_test.dart.strong.transformed.expect
new file mode 100644
index 0000000..81b63fc
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_initializer_arguments_assignable_test.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class X extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Foo<T extends self::X> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::Foo::T x;
+  constructor fromX(self::X _init) → void
+    : this self::Foo::_internal(x: _init as{TypeError} self::Foo::T)
+    ;
+  constructor fromT(self::Foo::T _init) → void
+    : this self::Foo::_internal(x: _init)
+    ;
+  constructor _internal({self::Foo::T x = null}) → void
+    : self::Foo::x = x, super core::Object::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.direct.transformed.expect b/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.direct.transformed.expect
new file mode 100644
index 0000000..d42aaa0
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo<T extends core::Object> extends core::Object {
+  field self::Foo::T x;
+  constructor from(core::String _init) → void
+    : this self::Foo::_internal(x: _init)
+    ;
+  constructor _internal({self::Foo::T x = null}) → void
+    : self::Foo::x = x, super core::Object::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.transformed.expect b/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.transformed.expect
new file mode 100644
index 0000000..910fa36
--- /dev/null
+++ b/pkg/front_end/testcases/redirecting_initializer_arguments_test.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::Foo::T x;
+  constructor from(core::String _init) → void
+    : this self::Foo::_internal(x: let final dynamic #t1 = _init in let dynamic _ = null in invalid-expression "pkg/front_end/testcases/redirecting_initializer_arguments_test.dart:12:46: Error: A value of type 'dart.core::String' can't be assigned to a variable of type '#lib1::Foo::T'.
+Try changing the type of the left hand side, or casting the right hand side to '#lib1::Foo::T'.
+  Foo.from(String _init) : this._internal(x: _init);
+                                             ^")
+    ;
+  constructor _internal({self::Foo::T x = null}) → void
+    : self::Foo::x = x, super core::Object::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.direct.transformed.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.direct.transformed.expect
new file mode 100644
index 0000000..8a13842
--- /dev/null
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+class A extends core::Object {
+  static field dynamic _redirecting# = <dynamic>[self::A::•];
+  const constructor empty() → void
+    : super core::Object::•()
+    ;
+  static factory •() → self::A
+    let dynamic #redirecting_factory = self::B::• in let core::String #typeArg0 = null in invalid-expression;
+}
+class B<T extends core::Object> extends self::A {
+  const constructor •() → void
+    : super self::A::empty()
+    ;
+  method toString() → dynamic
+    return "${self::B::T}";
+}
+static method main() → void {
+  exp::Expect::equals("${const self::B::•<core::String>()}", "String");
+}
diff --git a/pkg/front_end/testcases/redirection_type_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/redirection_type_arguments.dart.strong.transformed.expect
new file mode 100644
index 0000000..f69d118
--- /dev/null
+++ b/pkg/front_end/testcases/redirection_type_arguments.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "package:expect/expect.dart" as exp;
+
+class A extends core::Object {
+  static field dynamic _redirecting# = <dynamic>[self::A::•];
+  const constructor empty() → void
+    : super core::Object::•()
+    ;
+  static factory •() → self::A
+    let<BottomType> #redirecting_factory = self::B::• in let core::String #typeArg0 = null in invalid-expression;
+}
+class B<T extends core::Object> extends self::A {
+  const constructor •() → void
+    : super self::A::empty()
+    ;
+  method toString() → core::String
+    return "${self::B::T}";
+}
+static method main() → void {
+  exp::Expect::equals("${const self::B::•<core::String>()}", "String");
+}
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29937.dart.direct.transformed.expect
new file mode 100644
index 0000000..d6d0df8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29937.dart:6:4: Error: A function expression can't have a name.
+  [f() {}];
+   ^"]/* from null */;
+static method main() → dynamic {
+  <dynamic>[let final () → dynamic f = () → dynamic {} in f];
+}
diff --git a/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect
new file mode 100644
index 0000000..8a2672b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29937.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29937.dart:6:4: Error: A function expression can't have a name.
+  [f() {}];
+   ^"]/* from null */;
+static method main() → dynamic {
+  <() → core::Null>[let final () → core::Null f = () → core::Null {} in f];
+}
diff --git a/pkg/front_end/testcases/regress/issue_29940.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29940.dart.direct.transformed.expect
new file mode 100644
index 0000000..b13d5e8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29940.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic {
+  dynamic a = "";
+  invalid-type c = null;
+}
diff --git a/pkg/front_end/testcases/regress/issue_29940.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29940.dart.strong.transformed.expect
new file mode 100644
index 0000000..678b455
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29940.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29940.dart:7:3: Error: 'a.b' isn't a type.
+  a.b c = null;
+  ^^^"]/* from null */;
+static method main() → dynamic {
+  core::String a = "";
+  invalid-type c = null;
+}
diff --git a/pkg/front_end/testcases/regress/issue_29941.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29941.dart.direct.transformed.expect
new file mode 100644
index 0000000..eea6787
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29941.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  dynamic a = "";
+  invalid-expression "pkg/front_end/testcases/regress/issue_29941.dart:7:5: Error: Expected an identifier, but got '\"\"'.
+  a.\"\";
+    ^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29941.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29941.dart.strong.transformed.expect
new file mode 100644
index 0000000..5c24424
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29941.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method bad() → dynamic {
+  core::String a = "";
+  invalid-expression "pkg/front_end/testcases/regress/issue_29941.dart:7:5: Error: Expected an identifier, but got '\"\"'.
+  a.\"\";
+    ^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29942.dart.direct.transformed.expect
new file mode 100644
index 0000000..16847ca
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
+Try adding {}.
+f() =
+    ^", "pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
+h() => null;
+^"]/* from null */;
+static method main() → dynamic {}
+static method f() → dynamic
+  return let final () → dynamic h = () → dynamic => null in h;
diff --git a/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect
new file mode 100644
index 0000000..4087b61
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29942.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29942.dart:8:5: Error: Expected a function body or '=>'.
+Try adding {}.
+f() =
+    ^", "pkg/front_end/testcases/regress/issue_29942.dart:10:1: Error: A function expression can't have a name.
+h() => null;
+^"]/* from null */;
+static method main() → dynamic {}
+static method f() → dynamic
+  return let final () → core::Null h = () → core::Null => null in h;
diff --git a/pkg/front_end/testcases/regress/issue_29943.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29943.dart.direct.transformed.expect
new file mode 100644
index 0000000..69b4062
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29943.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  invalid-expression "pkg/front_end/testcases/regress/issue_29943.dart:6:5: Error: Expected an identifier, but got '('.
+  x.(null);
+    ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29943.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29943.dart.strong.transformed.expect
new file mode 100644
index 0000000..69b4062
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29943.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  invalid-expression "pkg/front_end/testcases/regress/issue_29943.dart:6:5: Error: Expected an identifier, but got '('.
+  x.(null);
+    ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29944.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29944.dart.direct.transformed.expect
new file mode 100644
index 0000000..8c99e27
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29944.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic C = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
+  var C;
+      ^"]/* from null */;
+static method main() → dynamic {
+  new self::C::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_29944.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29944.dart.strong.transformed.expect
new file mode 100644
index 0000000..8c99e27
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29944.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic C = null;
+  constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29944.dart:7:7: Error: A class member can't have the same name as the enclosing class.
+  var C;
+      ^"]/* from null */;
+static method main() → dynamic {
+  new self::C::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_29945.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29945.dart.direct.transformed.expect
new file mode 100644
index 0000000..186616b
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29945.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+
+static method main() → dynamic {
+  invalid-type x = null;
+}
diff --git a/pkg/front_end/testcases/regress/issue_29945.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29945.dart.strong.transformed.expect
new file mode 100644
index 0000000..dd9f49e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29945.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29945.dart:6:3: Error: 's.bool' can't be used as a type because 's' isn't defined.
+  s.bool x = null;
+  ^^^^^^"]/* from null */;
+static method main() → dynamic {
+  invalid-type x = null;
+}
diff --git a/pkg/front_end/testcases/regress/issue_29976.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29976.dart.direct.transformed.expect
new file mode 100644
index 0000000..d2f376d
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29976.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static method #main() → dynamic {
+  throw "pkg/front_end/testcases/regress/issue_29976.dart:8:3: Error: Expected a String, but got ')'.
+  )
+  ^";
+}
diff --git a/pkg/front_end/testcases/regress/issue_29976.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29976.dart.strong.transformed.expect
new file mode 100644
index 0000000..d2f376d
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29976.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static method #main() → dynamic {
+  throw "pkg/front_end/testcases/regress/issue_29976.dart:8:3: Error: Expected a String, but got ')'.
+  )
+  ^";
+}
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29977.dart.direct.transformed.expect
new file mode 100644
index 0000000..3acc695
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
+  Invalid MIME type.
+import 'data:async';
+                  ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29977.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29977.dart.strong.transformed.expect
new file mode 100644
index 0000000..3acc695
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29977.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29977.dart:5:19: Error: Couldn't parse URI 'data:async':
+  Invalid MIME type.
+import 'data:async';
+                  ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29978.dart.direct.transformed.expect
new file mode 100644
index 0000000..cb1a576
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29978.dart:8:13: Error: A function expression can't have a name.
+  foo(null, f() {});
+            ^"]/* from null */;
+static method foo(dynamic a, dynamic b) → dynamic
+  return null;
+static method main() → dynamic {
+  self::foo(null, let final () → dynamic f = () → dynamic {} in f);
+}
diff --git a/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect
new file mode 100644
index 0000000..88d3285
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29978.dart.strong.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29978.dart:8:13: Error: A function expression can't have a name.
+  foo(null, f() {});
+            ^"]/* from null */;
+static method foo(dynamic a, dynamic b) → dynamic
+  return null;
+static method main() → dynamic {
+  self::foo(null, let final () → core::Null f = () → core::Null {} in f);
+}
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29979.dart.direct.transformed.expect
new file mode 100644
index 0000000..4a66e4c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29979.dart:6:4: Error: A function expression can't have a name.
+  (f() {})();
+   ^"]/* from null */;
+static method main() → dynamic {
+  (let final () → dynamic f = () → dynamic {} in f).call();
+}
diff --git a/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect
new file mode 100644
index 0000000..b782e0e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29979.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29979.dart:6:4: Error: A function expression can't have a name.
+  (f() {})();
+   ^"]/* from null */;
+static method main() → dynamic {
+  (let final () → core::Null f = () → core::Null {} in f).call();
+}
diff --git a/pkg/front_end/testcases/regress/issue_29980.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29980.dart.direct.transformed.expect
new file mode 100644
index 0000000..15d1958
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29980.dart.direct.transformed.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+
+static method main() → dynamic {
+  invalid-type z;
+}
diff --git a/pkg/front_end/testcases/regress/issue_29980.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29980.dart.strong.transformed.expect
new file mode 100644
index 0000000..d73d7b3
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29980.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29980.dart:6:3: Error: 'x.y' can't be used as a type because 'x' isn't defined.
+  x.y z;
+  ^^^"]/* from null */;
+static method main() → dynamic {
+  invalid-type z;
+}
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29981.dart.direct.transformed.expect
new file mode 100644
index 0000000..6da0dfb
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  field self::C<dynamic> field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::print(new self::C::•<dynamic>());
+}
diff --git a/pkg/front_end/testcases/regress/issue_29981.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29981.dart.strong.transformed.expect
new file mode 100644
index 0000000..1aa328a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29981.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  field self::C<dynamic> field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29981.dart:6:3: Error: 'C' expects 1 type arguments.
+  C<String, String> field;
+  ^"]/* from null */;
+static method main() → dynamic {
+  core::print(new self::C::•<dynamic>());
+}
diff --git a/pkg/front_end/testcases/regress/issue_29983.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29983.dart.direct.transformed.expect
new file mode 100644
index 0000000..21d9fec
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29983.dart.direct.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method f() → dynamic /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<dynamic> :iterator) → core::bool yielding {
+    {
+      invalid-expression "pkg/front_end/testcases/regress/issue_29983.dart:7:3: Error: 'sync*' and 'async*' can't return a value.
+  return missing;
+  ^";
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<dynamic>(:sync_op);
+}
+static method g() → dynamic /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<dynamic> :iterator) → core::bool yielding {
+    invalid-expression "pkg/front_end/testcases/regress/issue_29983.dart:11:14: Error: 'sync*' and 'async*' can't return a value.
+g() sync* => dummy;
+             ^";
+    return false;
+  }
+  return new core::_SyncIterable::•<dynamic>(:sync_op);
+}
+static method h() → dynamic /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<dynamic> :iterator) → core::bool yielding {
+    {
+      (() → dynamic => "return").call();
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<dynamic>(:sync_op);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect
new file mode 100644
index 0000000..7e6dc8d
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29983.dart.strong.transformed.expect
@@ -0,0 +1,45 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29983.dart:7:10: Error: Getter not found: 'missing'.
+  return missing;
+         ^^^^^^^", "pkg/front_end/testcases/regress/issue_29983.dart:11:14: Error: Getter not found: 'dummy'.
+g() sync* => dummy;
+             ^^^^^"]/* from null */;
+static method f() → dynamic /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<dynamic> :iterator) → core::bool yielding {
+    {
+      invalid-expression "pkg/front_end/testcases/regress/issue_29983.dart:7:3: Error: 'sync*' and 'async*' can't return a value.
+  return missing;
+  ^";
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<dynamic>(:sync_op);
+}
+static method g() → dynamic /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<dynamic> :iterator) → core::bool yielding {
+    invalid-expression "pkg/front_end/testcases/regress/issue_29983.dart:11:14: Error: 'sync*' and 'async*' can't return a value.
+g() sync* => dummy;
+             ^";
+    return false;
+  }
+  return new core::_SyncIterable::•<dynamic>(:sync_op);
+}
+static method h() → dynamic /* originally sync* */ {
+  dynamic :await_jump_var = 0;
+  dynamic :await_ctx_var;
+  function :sync_op(core::_SyncIterator<dynamic> :iterator) → core::bool yielding {
+    {
+      (() → core::String => "return").call();
+    }
+    return false;
+  }
+  return new core::_SyncIterable::•<dynamic>(:sync_op);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
new file mode 100644
index 0000000..f52c009
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Previous use of 'i'.
+  for (int i = i;; false) {}
+               ^"]/* from null */;
+static method bad() → dynamic {
+  for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+  for (int i = i;; false) {}
+           ^"; ; false) {
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
new file mode 100644
index 0000000..95a6e96
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29984.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Getter not found: 'i'.
+  for (int i = i;; false) {}
+               ^", "pkg/front_end/testcases/regress/issue_29984.dart:6:16: Error: Previous use of 'i'.
+  for (int i = i;; false) {}
+               ^"]/* from null */;
+static method bad() → dynamic {
+  for (final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_29984.dart:6:12: Error: Can't declare 'i' because it was already used in this scope.
+  for (int i = i;; false) {}
+           ^"; ; false) {
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29985.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29985.dart.direct.transformed.expect
new file mode 100644
index 0000000..f758e0f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29985.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: The non-ASCII character '\u55357\u56603' (U+1F51B) can't be used in identifiers, only in strings and comments.
+Try using an US-ASCII letter, a digit, '_' (an underscore), or '\$' (a dollar sign).
+  \u55357\u56603
+  ^", "pkg/front_end/testcases/regress/issue_29985.dart:7:1: Error: Expected ';' before this.
+}
+^"]/* from null */;
+static method bad() → dynamic {
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#🔛, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29985.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29985.dart.strong.transformed.expect
new file mode 100644
index 0000000..a54d2f6
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29985.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: The non-ASCII character '\u55357\u56603' (U+1F51B) can't be used in identifiers, only in strings and comments.
+Try using an US-ASCII letter, a digit, '_' (an underscore), or '\$' (a dollar sign).
+  \u55357\u56603
+  ^", "pkg/front_end/testcases/regress/issue_29985.dart:7:1: Error: Expected ';' before this.
+}
+^", "pkg/front_end/testcases/regress/issue_29985.dart:6:3: Error: Getter not found: '\u55357\u56603'.
+  \u55357\u56603
+  ^^"]/* from null */;
+static method bad() → dynamic {
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#🔛, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29986.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29986.dart.direct.transformed.expect
new file mode 100644
index 0000000..fc0df85
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29986.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
+Try adding {}.
+C(this.name);
+            ^", "pkg/front_end/testcases/regress/issue_29986.dart:8:3: Error: 'this' parameters can only be used on constructors.
+C(this.name);
+  ^"]/* from null */;
+static method main() → dynamic {}
+static abstract method C(dynamic name) → dynamic;
diff --git a/pkg/front_end/testcases/regress/issue_29986.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29986.dart.strong.transformed.expect
new file mode 100644
index 0000000..fc0df85
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29986.dart.strong.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29986.dart:8:13: Error: Expected a function body or '=>'.
+Try adding {}.
+C(this.name);
+            ^", "pkg/front_end/testcases/regress/issue_29986.dart:8:3: Error: 'this' parameters can only be used on constructors.
+C(this.name);
+  ^"]/* from null */;
+static method main() → dynamic {}
+static abstract method C(dynamic name) → dynamic;
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_29987.dart.direct.transformed.expect
new file mode 100644
index 0000000..51e6889
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.direct.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
+  Illegal scheme character.
+import \"dart_:core\";
+            ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_29987.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_29987.dart.strong.transformed.expect
new file mode 100644
index 0000000..51e6889
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_29987.dart.strong.transformed.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_29987.dart:5:13: Error: Couldn't parse URI 'dart_:core':
+  Illegal scheme character.
+import \"dart_:core\";
+            ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_30834.dart.direct.transformed.expect
new file mode 100644
index 0000000..de8a7cd
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set A(dynamic v) → dynamic {}
+}
+static method main() → dynamic {
+  dynamic a = new self::A::•();
+  a.A = 5;
+}
diff --git a/pkg/front_end/testcases/regress/issue_30834.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_30834.dart.strong.transformed.expect
new file mode 100644
index 0000000..21d109e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30834.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set A(dynamic v) → void {}
+}
+static method main() → dynamic {
+  self::A a = new self::A::•();
+  a.{self::A::A} = 5;
+}
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_30836.dart.direct.transformed.expect
new file mode 100644
index 0000000..3f4c856
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x = null;
+  constructor •() → void
+    : super core::Object::•() {}
+}
diff --git a/pkg/front_end/testcases/regress/issue_30836.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_30836.dart.strong.transformed.expect
new file mode 100644
index 0000000..3f4c856
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30836.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x = null;
+  constructor •() → void
+    : super core::Object::•() {}
+}
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_30838.dart.direct.transformed.expect
new file mode 100644
index 0000000..f535fa7
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Foo<S extends core::Object> = <T extends core::Object>(T) → S;
+class A extends core::Object {
+  field <T extends core::Object>(T) → core::int f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    this.f<core::String>("hello");
+  }
+}
+static method foo<T extends core::Object>(self::foo::T x) → core::int
+  return 3;
+static method bar() → <T extends core::Object>(T) → core::int
+  return self::foo;
+static method test1() → void {
+  self::bar().call<core::String>("hello");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_30838.dart.strong.transformed.expect
new file mode 100644
index 0000000..c2c1595
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Foo<S extends core::Object> = <T extends core::Object>(T) → S;
+class A extends core::Object {
+  field <T extends core::Object>(T) → core::int f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    this.{self::A::f}<core::String>("hello");
+  }
+}
+static method foo<T extends core::Object>(self::foo::T x) → core::int
+  return 3;
+static method bar() → <T extends core::Object>(T) → core::int
+  return self::foo;
+static method test1() → void {
+  self::bar().call<core::String>("hello");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_30981.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_30981.dart.direct.transformed.expect
new file mode 100644
index 0000000..e946ea8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30981.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get A() → dynamic {
+    core::print("Actually, I'm a getter, not a constructor.");
+  }
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
+  get A {
+      ^"]/* from null */;
+static method main() → dynamic {
+  new self::A::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_30981.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_30981.dart.strong.transformed.expect
new file mode 100644
index 0000000..e946ea8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30981.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get A() → dynamic {
+    core::print("Actually, I'm a getter, not a constructor.");
+  }
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_30981.dart:6:7: Error: A class member can't have the same name as the enclosing class.
+  get A {
+      ^"]/* from null */;
+static method main() → dynamic {
+  new self::A::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_30994.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_30994.dart.direct.transformed.expect
new file mode 100644
index 0000000..a45c042
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30994.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library lib;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
+part '\$foo';
+      ^", "pkg/front_end/testcases/regress/issue_30994.dart:7:7: Error: Can't use string interpolation in a URI.
+part '\$foo/bar';
+      ^", "pkg/front_end/testcases/regress/issue_30994.dart:8:7: Error: Can't use string interpolation in a URI.
+part '\$for/bar';
+      ^", "pkg/front_end/testcases/regress/issue_30994.dart:9:7: Error: Can't use string interpolation in a URI.
+part '\${true}';
+      ^", "pkg/front_end/testcases/regress/issue_30994.dart:10:10: Error: Can't use string interpolation in a URI.
+part 'the\${1}thing';
+         ^", "pkg/front_end/testcases/regress/issue_30994.dart:11:12: Error: Can't use string interpolation in a URI.
+part 'part_\$foo\${'a'}.dart';
+           ^", "pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
+part 'part_\${'a'}_\$foo.dart';
+           ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_30994.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_30994.dart.strong.transformed.expect
new file mode 100644
index 0000000..a45c042
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30994.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library lib;
+import self as self;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_30994.dart:6:7: Error: Can't use string interpolation in a URI.
+part '\$foo';
+      ^", "pkg/front_end/testcases/regress/issue_30994.dart:7:7: Error: Can't use string interpolation in a URI.
+part '\$foo/bar';
+      ^", "pkg/front_end/testcases/regress/issue_30994.dart:8:7: Error: Can't use string interpolation in a URI.
+part '\$for/bar';
+      ^", "pkg/front_end/testcases/regress/issue_30994.dart:9:7: Error: Can't use string interpolation in a URI.
+part '\${true}';
+      ^", "pkg/front_end/testcases/regress/issue_30994.dart:10:10: Error: Can't use string interpolation in a URI.
+part 'the\${1}thing';
+         ^", "pkg/front_end/testcases/regress/issue_30994.dart:11:12: Error: Can't use string interpolation in a URI.
+part 'part_\$foo\${'a'}.dart';
+           ^", "pkg/front_end/testcases/regress/issue_30994.dart:12:12: Error: Can't use string interpolation in a URI.
+part 'part_\${'a'}_\$foo.dart';
+           ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31157.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31157.dart.direct.transformed.expect
new file mode 100644
index 0000000..895f75f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31157.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  return invalid-expression "pkg/front_end/testcases/regress/issue_31157.dart:6:16: Error: Expected an identifier, but got '('.
+  return null?.(1);
+               ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31157.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31157.dart.strong.transformed.expect
new file mode 100644
index 0000000..895f75f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31157.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  return invalid-expression "pkg/front_end/testcases/regress/issue_31157.dart:6:16: Error: Expected an identifier, but got '('.
+  return null?.(1);
+               ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31180.dart.direct.transformed.expect
new file mode 100644
index 0000000..624821f2
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  return invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
+  return null?.[1];
+               ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
new file mode 100644
index 0000000..624821f2
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31180.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  return invalid-expression "pkg/front_end/testcases/regress/issue_31180.dart:6:16: Error: Expected an identifier, but got '['.
+  return null?.[1];
+               ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31181.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31181.dart.direct.transformed.expect
new file mode 100644
index 0000000..b89cafc
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31181.dart.direct.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Foo<T extends core::Object> = <T extends core::Object>(T) → T;
+static field <T extends core::Object>(T) → T x;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31181.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31181.dart.strong.transformed.expect
new file mode 100644
index 0000000..b89cafc
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31181.dart.strong.transformed.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Foo<T extends core::Object> = <T extends core::Object>(T) → T;
+static field <T extends core::Object>(T) → T x;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31183.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31183.dart.direct.transformed.expect
new file mode 100644
index 0000000..3911009
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31183.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic operator = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator unary-() → dynamic
+    return 0;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_31183.dart:6:3: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+Try adding the name of the type of the variable or the keyword 'var'.
+  operator unary- => 0;
+  ^^^^^^^^", "pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Expected ';' before this.
+  operator unary- => 0;
+           ^^^^^", "pkg/front_end/testcases/regress/issue_31183.dart:6:17: Error: Operator declarations must be preceeded by the keyword 'operator'.
+Try adding the keyword 'operator'.
+  operator unary- => 0;
+                ^", "pkg/front_end/testcases/regress/issue_31183.dart:6:17: Error: A method declaration needs an explicit list of parameters.
+Try adding a parameter list to the method declaration.
+  operator unary- => 0;
+                ^"]/* from null */;
+static method main() → dynamic {
+  new self::C::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_31183.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31183.dart.strong.transformed.expect
new file mode 100644
index 0000000..3911009
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31183.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic operator = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator unary-() → dynamic
+    return 0;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_31183.dart:6:3: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
+Try adding the name of the type of the variable or the keyword 'var'.
+  operator unary- => 0;
+  ^^^^^^^^", "pkg/front_end/testcases/regress/issue_31183.dart:6:12: Error: Expected ';' before this.
+  operator unary- => 0;
+           ^^^^^", "pkg/front_end/testcases/regress/issue_31183.dart:6:17: Error: Operator declarations must be preceeded by the keyword 'operator'.
+Try adding the keyword 'operator'.
+  operator unary- => 0;
+                ^", "pkg/front_end/testcases/regress/issue_31183.dart:6:17: Error: A method declaration needs an explicit list of parameters.
+Try adding a parameter list to the method declaration.
+  operator unary- => 0;
+                ^"]/* from null */;
+static method main() → dynamic {
+  new self::C::•();
+}
diff --git a/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect
new file mode 100644
index 0000000..f7b5642
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31184.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_31184.dart:6:21: Error: Expected ';' before this.
+  for (int i = 0, i > 10; i++) {}
+                    ^", "pkg/front_end/testcases/regress/issue_31184.dart:6:21: Error: Expected an identifier, but got '>'.
+  for (int i = 0, i > 10; i++) {}
+                    ^"]/* from null */;
+static method bad() → dynamic {
+  for (core::int i = 0, final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31184.dart:6:19: Error: 'i' already declared in this scope.
+  for (int i = 0, i > 10; i++) {}
+                  ^"; (throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#, 33, const <core::Type>[], const <dynamic>[], core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})))).>(10); i = i.+(1)) {
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31186.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31186.dart.direct.transformed.expect
new file mode 100644
index 0000000..db52098
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31186.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  return invalid-expression "pkg/front_end/testcases/regress/issue_31186.dart:6:16: Error: Expected an identifier, but got 'true'.
+  return null?.true;
+               ^^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31186.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31186.dart.strong.transformed.expect
new file mode 100644
index 0000000..db52098
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31186.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  return invalid-expression "pkg/front_end/testcases/regress/issue_31186.dart:6:16: Error: Expected an identifier, but got 'true'.
+  return null?.true;
+               ^^^^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31187.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31187.dart.direct.transformed.expect
new file mode 100644
index 0000000..df2ebb4
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31187.dart.direct.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  return invalid-expression "pkg/front_end/testcases/regress/issue_31187.dart:6:16: Error: Expected an identifier, but got '1'.
+  return null?.1;
+               ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31187.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31187.dart.strong.transformed.expect
new file mode 100644
index 0000000..df2ebb4
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31187.dart.strong.transformed.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method bad() → dynamic {
+  return invalid-expression "pkg/front_end/testcases/regress/issue_31187.dart:6:16: Error: Expected an identifier, but got '1'.
+  return null?.1;
+               ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31190.dart.direct.transformed.expect
new file mode 100644
index 0000000..4fad235
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.direct.transformed.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Typed<T extends core::Object> extends core::Object {
+  field self::Typed::T v = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect
new file mode 100644
index 0000000..2eacbb9
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31190.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Typed<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::Typed::T v = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_31190.dart: Error: Can't use type arguments with type variable 'T'.
+Try removing the type arguments.", "pkg/front_end/testcases/regress/issue_31190.dart:6:5: Error: 'U' isn't a type.
+  T<U> v;
+    ^", "pkg/front_end/testcases/regress/issue_31190.dart:6:3: Error: 'T' expects 0 type arguments.
+  T<U> v;
+  ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31192.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31192.dart.direct.transformed.expect
new file mode 100644
index 0000000..29c3f87
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31192.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Increment extends core::Object {
+  field core::int x = null;
+  constructor •() → void
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: '' isn't an instance field of this class.
+  Increment() : x++ {}
+                ^" {}
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Expected an assignment after the field name.
+To initialize a field, use the syntax 'name = value'.
+  Increment() : x++ {}
+                ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31192.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31192.dart.strong.transformed.expect
new file mode 100644
index 0000000..29c3f87
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31192.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Increment extends core::Object {
+  field core::int x = null;
+  constructor •() → void
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: '' isn't an instance field of this class.
+  Increment() : x++ {}
+                ^" {}
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_31192.dart:7:17: Error: Expected an assignment after the field name.
+To initialize a field, use the syntax 'name = value'.
+  Increment() : x++ {}
+                ^"]/* from null */;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31198.dart.direct.transformed.expect
new file mode 100644
index 0000000..6421b2c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  constructor •() → void
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+  B(): super().foo() {}
+       ^".foo() {}
+}
+static method bad() → dynamic {
+  new self::B::•();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31198.dart.strong.transformed.expect
new file mode 100644
index 0000000..6421b2c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  constructor •() → void
+    : final dynamic #t1 = invalid-expression "pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+  B(): super().foo() {}
+       ^".foo() {}
+}
+static method bad() → dynamic {
+  new self::B::•();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31213.dart.direct.transformed.expect
new file mode 100644
index 0000000..860b081
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef C<A extends core::Object, K extends core::Object> = <B extends core::Object>(A, K, B) → core::int;
+typedef D<K extends core::Object> = <A extends core::Object>(core::int) → <B extends core::Object>(A, K, B) → core::int;
+static method producer<K extends core::Object>() → dynamic {
+  return <A extends core::Object>(core::int v1) → dynamic {
+    return <B extends core::Object>(A v2, self::producer::K v3, B v4) → dynamic => 0;
+  };
+}
+static method main() → dynamic {
+  assert(self::producer<core::String>() is <A extends core::Object>(core::int) → <B extends core::Object>(A, core::String, B) → core::int);
+}
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31213.dart.strong.transformed.expect
new file mode 100644
index 0000000..c6e0d5f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef C<A extends core::Object, K extends core::Object> = <B extends core::Object>(A, K, B) → core::int;
+typedef D<K extends core::Object> = <A extends core::Object>(core::int) → <B extends core::Object>(A, K, B) → core::int;
+static method producer<K extends core::Object>() → dynamic {
+  return <A extends core::Object>(core::int v1) → <B extends core::Object>(A, self::producer::K, B) → core::int {
+    return <B extends core::Object>(A v2, self::producer::K v3, B v4) → core::int => 0;
+  };
+}
+static method main() → dynamic {
+  assert(self::producer<core::String>() is <A extends core::Object>(core::int) → <B extends core::Object>(A, core::String, B) → core::int);
+}
diff --git a/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect
new file mode 100644
index 0000000..0161677
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31299.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field core::int m;
+  constructor •() → void
+    : self::A::m = 1, super core::Object::•()
+    ;
+  constructor foo() → void
+    : self::A::m = 2, super core::Object::•()
+    ;
+  method foo(core::int a, core::int b) → core::int
+    return a.+(b.*(this.{self::A::m}));
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_31299.dart:10:3: Error: Conflicts with member 'foo'.
+  A.foo() : m = 2;
+  ^", "pkg/front_end/testcases/regress/issue_31299.dart:11:7: Error: Conflicts with constructor 'A.foo'.
+  int foo(int a, int b) => a + b * m;
+      ^"]/* from null */;
+static method test() → dynamic {
+  new self::A::•().foo();
+  new self::A::•().foo(1, 2);
+  new self::A::foo();
+  throw new core::NoSuchMethodError::withInvocation(null, new core::_InvocationMirror::_withType(#foo, 32, const <core::Type>[], <dynamic>[1, 2].toList(growable: false), core::Map::unmodifiable<core::Symbol, dynamic>(const <core::Symbol, dynamic>{})));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31766.dart.direct.transformed.expect
new file mode 100644
index 0000000..ad01f98
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return null;
+}
+static method main() → dynamic {
+  function bar<T extends self::A>(T t) → void {
+    core::print("t.foo()=${t.foo()}");
+  }
+  bar.call(new self::A::•());
+  (<S extends self::A>(S s) → dynamic {
+    core::print("s.foo()=${s.foo()}");
+  }).call(new self::A::•());
+}
diff --git a/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
new file mode 100644
index 0000000..5228fa9
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31766.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → dynamic
+    return null;
+}
+static method main() → dynamic {
+  function bar<T extends self::A>(T t) → void {
+    core::print("t.foo()=${t.{self::A::foo}()}");
+  }
+  bar.call<self::A>(new self::A::•());
+  (<S extends self::A>(S s) → core::Null {
+    core::print("s.foo()=${s.{self::A::foo}()}");
+  }).call<self::A>(new self::A::•());
+}
diff --git a/pkg/front_end/testcases/regress/issue_31846.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31846.dart.direct.transformed.expect
new file mode 100644
index 0000000..960d4d1
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31846.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print(self::main is () → dynamic);
+  core::print((<T extends core::Object>(T x) → dynamic => x).runtimeType);
+  core::print((<T extends core::num>(T x) → dynamic => x).runtimeType);
+  core::print((<T extends core::Comparable<T>>(T x) → dynamic => x).runtimeType);
+}
diff --git a/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect
new file mode 100644
index 0000000..8a842f2
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31846.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::print(self::main is () → dynamic);
+  core::print((<T extends core::Object>(T x) → T => x).{core::Object::runtimeType});
+  core::print((<T extends core::num>(T x) → T => x).{core::Object::runtimeType});
+  core::print((<T extends core::Comparable<T>>(T x) → T => x).{core::Object::runtimeType});
+}
diff --git a/pkg/front_end/testcases/regress/issue_31996.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_31996.dart.direct.transformed.expect
new file mode 100644
index 0000000..7b5a76e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31996.dart.direct.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Base extends core::Object implements self::B<dynamic> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Child1 extends self::Base implements self::C<core::int> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Child2 extends self::Base implements self::C<core::double> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31996.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31996.dart.strong.transformed.expect
new file mode 100644
index 0000000..7b5a76e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31996.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+abstract class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Base extends core::Object implements self::B<dynamic> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Child1 extends self::Base implements self::C<core::int> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+class Child2 extends self::Base implements self::C<core::double> {
+  synthetic constructor •() → void
+    : super self::Base::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_32182.dart.direct.transformed.expect
new file mode 100644
index 0000000..aeae487
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.direct.transformed.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return 42;
+}
+abstract class _C&A&M extends self::A<self::A<dynamic>> implements self::M {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  method m() → dynamic
+    return 42;
+}
+class C extends self::_C&A&M {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {
+  new self::C::•().m().+(1);
+}
diff --git a/pkg/front_end/testcases/regress/issue_32182.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_32182.dart.strong.transformed.expect
new file mode 100644
index 0000000..179409c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32182.dart.strong.transformed.expect
@@ -0,0 +1,31 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class M extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m() → dynamic
+    return 42;
+}
+abstract class _C&A&M extends self::A<self::A<dynamic>> implements self::M {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  method m() → dynamic
+    return 42;
+}
+class C extends self::_C&A&M {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+}
+static method main() → dynamic {
+  new self::C::•().{self::M::m}().+(1);
+}
diff --git a/pkg/front_end/testcases/regress/issue_32196.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_32196.dart.direct.transformed.expect
new file mode 100644
index 0000000..bf9d1e2
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32196.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::String name;
+  constructor get(core::String name) → void
+    : self::A::name = name, super core::Object::•()
+    ;
+  constructor set(core::String name) → void
+    : self::A::name = name, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  new self::A::get("get");
+  new self::A::set("set");
+}
diff --git a/pkg/front_end/testcases/regress/issue_32196.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_32196.dart.strong.transformed.expect
new file mode 100644
index 0000000..bf9d1e2
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32196.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::String name;
+  constructor get(core::String name) → void
+    : self::A::name = name, super core::Object::•()
+    ;
+  constructor set(core::String name) → void
+    : self::A::name = name, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  new self::A::get("get");
+  new self::A::set("set");
+}
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.direct.transformed.expect b/pkg/front_end/testcases/regress/issue_32200.dart.direct.transformed.expect
new file mode 100644
index 0000000..9857054
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field self::Foo self = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::Foo instance = new self::Foo::•();
+  instance.self = instance;
+}
diff --git a/pkg/front_end/testcases/regress/issue_32200.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_32200.dart.strong.transformed.expect
new file mode 100644
index 0000000..d4cce8e
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_32200.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field self::Foo self = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/regress/issue_32200.dart:8:3: Error: 'self.Foo' can't be used as a type because 'self' doesn't refer to an import prefix.
+  self.Foo self;
+  ^^^^^^^^"]/* from null */;
+static method main() → dynamic {
+  self::Foo instance = new self::Foo::•();
+  instance.{self::Foo::self} = instance;
+}
diff --git a/pkg/front_end/testcases/reorder_super.dart.direct.transformed.expect b/pkg/front_end/testcases/reorder_super.dart.direct.transformed.expect
new file mode 100644
index 0000000..4a2f96e
--- /dev/null
+++ b/pkg/front_end/testcases/reorder_super.dart.direct.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  field core::num x;
+  field core::String y;
+  constructor •(core::num x, core::String y) → void
+    : self::B::x = x, self::B::y = y, super core::Object::•() {
+    self::events = self::events.+("super(${this.{self::B::x}}, ${this.{self::B::y}})
+");
+  }
+}
+class C extends self::B {
+  final field dynamic z;
+  constructor •() → void
+    : final dynamic #t1 = self::f(1), final dynamic #t2 = self::g(2), self::C::z = self::f(3), super self::B::•(#t1, #t2)
+    ;
+}
+static field core::String events = "";
+static method f(dynamic x) → core::int {
+  self::events = self::events.+("f(${x})
+");
+  return 0;
+}
+static method g(dynamic x) → core::String {
+  self::events = self::events.+("g(${x})
+");
+  return "foo";
+}
+static method main() → dynamic {
+  new self::C::•();
+  if(!self::events.==("f(1)
+g(2)
+f(3)
+super(0, foo)
+")) {
+    throw "Unexpected sequence of events: ${self::events}";
+  }
+}
diff --git a/pkg/front_end/testcases/reorder_super.dart.strong.transformed.expect b/pkg/front_end/testcases/reorder_super.dart.strong.transformed.expect
new file mode 100644
index 0000000..cdd2ae0
--- /dev/null
+++ b/pkg/front_end/testcases/reorder_super.dart.strong.transformed.expect
@@ -0,0 +1,40 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  field core::num x;
+  field core::String y;
+  constructor •(core::num x, core::String y) → void
+    : self::B::x = x, self::B::y = y, super core::Object::•() {
+    self::events = self::events.{core::String::+}("super(${this.{self::B::x}}, ${this.{self::B::y}})
+");
+  }
+}
+class C extends self::B {
+  final field dynamic z;
+  constructor •() → void
+    : final core::int #t1 = self::f(1), final core::String #t2 = self::g(2), self::C::z = self::f(3), super self::B::•(#t1, #t2)
+    ;
+}
+static field core::String events = "";
+static method f(dynamic x) → core::int {
+  self::events = self::events.{core::String::+}("f(${x})
+");
+  return 0;
+}
+static method g(dynamic x) → core::String {
+  self::events = self::events.{core::String::+}("g(${x})
+");
+  return "foo";
+}
+static method main() → dynamic {
+  new self::C::•();
+  if(!self::events.{core::String::==}("f(1)
+g(2)
+f(3)
+super(0, foo)
+")) {
+    throw "Unexpected sequence of events: ${self::events}";
+  }
+}
diff --git a/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.direct.transformed.expect b/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.direct.transformed.expect
new file mode 100644
index 0000000..309defd
--- /dev/null
+++ b/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.direct.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method f(core::List<dynamic> x) → core::bool {
+  return x.expand((dynamic y) → dynamic {
+    return y.split(",");
+  }).any((dynamic y) → dynamic => y.==("z"));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.transformed.expect b/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.transformed.expect
new file mode 100644
index 0000000..31007c6
--- /dev/null
+++ b/pkg/front_end/testcases/return_with_unknown_type_in_context.dart.strong.transformed.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+static method f(core::List<dynamic> x) → core::bool {
+  return x.{core::Iterable::expand}<dynamic>((dynamic y) → core::Iterable<dynamic> {
+    return y.split(",") as{TypeError} core::Iterable<dynamic>;
+  }).{core::Iterable::any}((dynamic y) → core::bool => y.==("z"));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.direct.transformed.expect
new file mode 100644
index 0000000..044ccf6
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.direct.transformed.expect
@@ -0,0 +1,32 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → void {}
+  get g() → () → void
+    return null;
+  get h() → dynamic
+    return null;
+  method test() → void {
+    this.{self::C::f}();
+    this.{self::C::f}();
+    this.{self::C::g}();
+    this.{self::C::g}();
+    this.{self::C::h}();
+    this.{self::C::h}();
+  }
+}
+static method test(self::C c, () → void f, dynamic d) → void {
+  c.f();
+  f.call();
+  d.call();
+  d.f();
+  c.g();
+  c.h();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.strong.transformed.expect
new file mode 100644
index 0000000..c1938f2
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds.dart.strong.transformed.expect
@@ -0,0 +1,32 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F = () → void;
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → void {}
+  get g() → () → void
+    return null;
+  get h() → dynamic
+    return null;
+  method test() → void {
+    this.{self::C::f}();
+    this.{self::C::f}();
+    this.{self::C::g}();
+    this.{self::C::g}();
+    this.{self::C::h}();
+    this.{self::C::h}();
+  }
+}
+static method test(self::C c, () → void f, dynamic d) → void {
+  c.{self::C::f}();
+  f.call();
+  d.call();
+  d.f();
+  c.{self::C::g}();
+  c.{self::C::h}();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.direct.transformed.expect
new file mode 100644
index 0000000..d61a225
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → dynamic
+    return null;
+  method test() → void {
+    dynamic v1 = this.{self::C::x};
+    dynamic v2 = this.{self::C::x};
+    dynamic v3 = this.{self::C::y};
+    dynamic v4 = this.{self::C::y};
+  }
+}
+static method test(self::C c, dynamic d) → void {
+  dynamic v1 = c.x;
+  dynamic v2 = c.y;
+  dynamic v3 = d.x;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.strong.transformed.expect
new file mode 100644
index 0000000..18abd83
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_get.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → dynamic
+    return null;
+  method test() → void {
+    dynamic v1 = this.{self::C::x};
+    dynamic v2 = this.{self::C::x};
+    dynamic v3 = this.{self::C::y};
+    dynamic v4 = this.{self::C::y};
+  }
+}
+static method test(self::C c, dynamic d) → void {
+  dynamic v1 = c.{self::C::x};
+  dynamic v2 = c.{self::C::y};
+  dynamic v3 = d.x;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.direct.transformed.expect
new file mode 100644
index 0000000..2341dd8
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(dynamic value) → void {}
+  method test() → void {
+    this.{self::C::x} = null;
+    this.{self::C::x} = null;
+    this.{self::C::y} = null;
+    this.{self::C::y} = null;
+  }
+}
+static method test(self::C c, dynamic d) → void {
+  c.x = null;
+  c.y = null;
+  d.x = null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.strong.transformed.expect
new file mode 100644
index 0000000..b7006b5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_kinds_set.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(dynamic value) → void {}
+  method test() → void {
+    this.{self::C::x} = null;
+    this.{self::C::x} = null;
+    this.{self::C::y} = null;
+    this.{self::C::y} = null;
+  }
+}
+static method test(self::C c, dynamic d) → void {
+  c.{self::C::x} = null;
+  c.{self::C::y} = null;
+  d.x = null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.direct.transformed.expect
new file mode 100644
index 0000000..7108626
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call() → void {}
+}
+static method main() → dynamic {
+  () → void x = new self::C::•();
+}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..a7d91b4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call() → void {}
+}
+static method main() → dynamic {
+  () → void x = let final self::C #t1 = new self::C::•() in #t1.==(null) ?{() → void} null : #t1.{self::C::call};
+}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.direct.transformed.expect
new file mode 100644
index 0000000..3c40128
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call() → void {}
+}
+static method main() → dynamic {
+  asy::FutureOr<() → void> x = new self::C::•();
+}
diff --git a/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.transformed.expect
new file mode 100644
index 0000000..6429b52
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/call_method_implicit_tear_off_future_or.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call() → void {}
+}
+static method main() → dynamic {
+  asy::FutureOr<() → void> x = let final self::C #t1 = new self::C::•() in #t1.==(null) ?{() → void} null : #t1.{self::C::call};
+}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..cd8a1ec
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  field (self::C::T) → void y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → void {
+    dynamic x = this.{self::C::y};
+  }
+}
+static method g(self::C<core::num> c) → void {
+  dynamic x = c.y;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..c2e5212
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_field.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  generic-contravariant field (self::C::T) → void y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → void {
+    (self::C::T) → void x = this.{self::C::y};
+  }
+}
+static method g(self::C<core::num> c) → void {
+  (core::num) → void x = c.{self::C::y} as{TypeError} (core::num) → void;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.direct.transformed.expect
new file mode 100644
index 0000000..bf5d9be
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends (self::C::T) → void>(self::C::f::U x) → void {}
+}
+static method g(self::C<core::num> c) → void {
+  c.f<(core::Object) → void>((core::Object o) → dynamic {});
+}
+static method test() → void {
+  self::g(new self::C::•<core::int>());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
new file mode 100644
index 0000000..547faf4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_method_type_parameter.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends (self::C::T) → void>(self::C::f::U x) → void {}
+}
+static method g(self::C<core::num> c) → void {
+  c.{self::C::f}<(core::Object) → void>((core::Object o) → core::Null {});
+}
+static method test() → void {
+  self::g(new self::C::•<core::int>());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.direct.transformed.expect
new file mode 100644
index 0000000..5221de2
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1() → (self::C::T) → void {}
+  method f2() → core::List<(self::C::T) → void> {
+    return <dynamic>[this.{self::C::f1}()];
+  }
+}
+static method g1(self::C<core::num> c) → void {
+  dynamic x = c.f1();
+  core::print("hello");
+  x.call(1.5);
+}
+static method g2(self::C<core::num> c) → void {
+  (core::int) → void x = c.f1();
+  x.call(1);
+}
+static method g3(self::C<core::num> c) → void {
+  dynamic x = c.f2();
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.transformed.expect
new file mode 100644
index 0000000..adab8ca
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  generic-contravariant method f1() → (self::C::T) → void {}
+  generic-contravariant method f2() → core::List<(self::C::T) → void> {
+    return <(self::C::T) → void>[this.{self::C::f1}()];
+  }
+}
+static method g1(self::C<core::num> c) → void {
+  (core::num) → void x = c.{self::C::f1}() as{TypeError} (core::num) → void;
+  core::print("hello");
+  x.call(1.5);
+}
+static method g2(self::C<core::num> c) → void {
+  (core::int) → void x = c.{self::C::f1}() as{TypeError} (core::num) → void;
+  x.call(1);
+}
+static method g3(self::C<core::num> c) → void {
+  core::List<(core::num) → void> x = c.{self::C::f2}() as{TypeError} core::List<(core::num) → void>;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.direct.transformed.expect
new file mode 100644
index 0000000..8acd66a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1() → (self::C::T) → void {}
+  method f2() → core::List<(self::C::T) → void> {
+    return <dynamic>[this.{self::C::f1}()];
+  }
+}
+static method g1(self::C<core::num> c) → void {
+  dynamic x = let final dynamic #t1 = c in #t1.==(null) ? null : #t1.f1();
+  core::print("hello");
+  x.call(1.5);
+}
+static method g2(self::C<core::num> c) → void {
+  (core::int) → void x = let final dynamic #t2 = c in #t2.==(null) ? null : #t2.f1();
+  x.call(1);
+}
+static method g3(self::C<core::num> c) → void {
+  dynamic x = let final dynamic #t3 = c in #t3.==(null) ? null : #t3.f2();
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect
new file mode 100644
index 0000000..7635298
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_null_aware.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  generic-contravariant method f1() → (self::C::T) → void {}
+  generic-contravariant method f2() → core::List<(self::C::T) → void> {
+    return <(self::C::T) → void>[this.{self::C::f1}()];
+  }
+}
+static method g1(self::C<core::num> c) → void {
+  (core::num) → void x = let final self::C<core::num> #t1 = c in #t1.==(null) ?{(core::num) → void} null : #t1.{self::C::f1}() as{TypeError} (core::num) → void;
+  core::print("hello");
+  x.call(1.5);
+}
+static method g2(self::C<core::num> c) → void {
+  (core::int) → void x = let final self::C<core::num> #t2 = c in #t2.==(null) ?{(core::num) → void} null : #t2.{self::C::f1}() as{TypeError} (core::num) → void;
+  x.call(1);
+}
+static method g3(self::C<core::num> c) → void {
+  core::List<(core::num) → void> x = let final self::C<core::num> #t3 = c in #t3.==(null) ?{core::List<(core::num) → void>} null : #t3.{self::C::f2}() as{TypeError} core::List<(core::num) → void>;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.direct.transformed.expect
new file mode 100644
index 0000000..70ed6d7
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.direct.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+typedef G<T extends core::Object> = () → (T) → void;
+class C<T extends core::Object> extends core::Object {
+  field (self::C::T) → void _x;
+  constructor •((self::C::T) → void _x) → void
+    : self::C::_x = _x, super core::Object::•()
+    ;
+  method f() → (self::C::T) → void
+    return this.{self::C::_x};
+}
+static method g(self::C<core::num> c) → () → (core::num) → void {
+  return c.f;
+}
+static method h(core::int i) → void {
+  core::print("${i}");
+}
+static method test() → void {
+  dynamic x = self::g(new self::C::•<core::int>(self::h));
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..f667624
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_generic_return_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+typedef G<T extends core::Object> = () → (T) → void;
+class C<T extends core::Object> extends core::Object {
+  generic-contravariant field (self::C::T) → void _x;
+  constructor •((self::C::T) → void _x) → void
+    : self::C::_x = _x, super core::Object::•()
+    ;
+  generic-contravariant method f() → (self::C::T) → void
+    return this.{self::C::_x};
+}
+static method g(self::C<core::num> c) → () → (core::num) → void {
+  return c.{self::C::f} as{TypeError} () → (core::num) → void;
+}
+static method h(core::int i) → void {
+  core::print("${i}");
+}
+static method test() → void {
+  () → (core::num) → void x = self::g(new self::C::•<core::int>(self::h));
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.direct.transformed.expect
new file mode 100644
index 0000000..e4fcea0
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  field (self::C::T) → void y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(self::C::T value) → void {
+    this.{self::C::y}(value);
+  }
+}
+static method g(self::C<core::num> c) → void {
+  c.y(1.5);
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.transformed.expect
new file mode 100644
index 0000000..88625d3
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  generic-contravariant field (self::C::T) → void y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(generic-covariant-impl generic-covariant-interface self::C::T value) → void {
+    this.{self::C::y}(value);
+  }
+}
+static method g(self::C<core::num> c) → void {
+  (c.{self::C::y} as{TypeError} (core::num) → void).call(1.5);
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.direct.transformed.expect
new file mode 100644
index 0000000..012a192
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.direct.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get f1() → (self::C::T) → void
+    return null;
+  get f2() → core::List<(self::C::T) → void> {
+    return <dynamic>[this.{self::C::f1}];
+  }
+}
+static method g1(self::C<core::num> c) → void {
+  dynamic x = c.f1;
+  core::print("hello");
+  x.call(1.5);
+}
+static method g2(self::C<core::num> c) → void {
+  (core::int) → void x = c.f1;
+  x.call(1);
+}
+static method g3(self::C<core::num> c) → void {
+  dynamic x = c.f2;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.transformed.expect
new file mode 100644
index 0000000..5c3e2d2
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return.dart.strong.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  generic-contravariant get f1() → (self::C::T) → void
+    return null;
+  generic-contravariant get f2() → core::List<(self::C::T) → void> {
+    return <(self::C::T) → void>[this.{self::C::f1}];
+  }
+}
+static method g1(self::C<core::num> c) → void {
+  (core::num) → void x = c.{self::C::f1} as{TypeError} (core::num) → void;
+  core::print("hello");
+  x.call(1.5);
+}
+static method g2(self::C<core::num> c) → void {
+  (core::int) → void x = c.{self::C::f1} as{TypeError} (core::num) → void;
+  x.call(1);
+}
+static method g3(self::C<core::num> c) → void {
+  core::List<(core::num) → void> x = c.{self::C::f2} as{TypeError} core::List<(core::num) → void>;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.direct.transformed.expect
new file mode 100644
index 0000000..7b9c2c6
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.direct.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get f1() → (self::C::T) → void
+    return null;
+  get f2() → core::List<(self::C::T) → void> {
+    return <dynamic>[this.{self::C::f1}];
+  }
+}
+static method g1(self::C<core::num> c) → void {
+  dynamic x = let final dynamic #t1 = c in #t1.==(null) ? null : #t1.f1;
+  core::print("hello");
+  x.call(1.5);
+}
+static method g2(self::C<core::num> c) → void {
+  (core::int) → void x = let final dynamic #t2 = c in #t2.==(null) ? null : #t2.f1;
+  x.call(1);
+}
+static method g3(self::C<core::num> c) → void {
+  dynamic x = let final dynamic #t3 = c in #t3.==(null) ? null : #t3.f2;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect
new file mode 100644
index 0000000..fcd0c39
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/contravariant_getter_return_null_aware.dart.strong.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  generic-contravariant get f1() → (self::C::T) → void
+    return null;
+  generic-contravariant get f2() → core::List<(self::C::T) → void> {
+    return <(self::C::T) → void>[this.{self::C::f1}];
+  }
+}
+static method g1(self::C<core::num> c) → void {
+  (core::num) → void x = let final self::C<core::num> #t1 = c in #t1.==(null) ?{(core::num) → void} null : #t1.{self::C::f1} as{TypeError} (core::num) → void;
+  core::print("hello");
+  x.call(1.5);
+}
+static method g2(self::C<core::num> c) → void {
+  (core::int) → void x = let final self::C<core::num> #t2 = c in #t2.==(null) ?{(core::num) → void} null : #t2.{self::C::f1} as{TypeError} (core::num) → void;
+  x.call(1);
+}
+static method g3(self::C<core::num> c) → void {
+  core::List<(core::num) → void> x = let final self::C<core::num> #t3 = c in #t3.==(null) ?{core::List<(core::num) → void>} null : #t3.{self::C::f2} as{TypeError} core::List<(core::num) → void>;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.direct.transformed.expect
new file mode 100644
index 0000000..b0a70d9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends self::C::T>(self::C::f::U x) → void {}
+  method g1<U extends self::C::T>() → void {
+    this.{self::C::f}<self::C::g1::U>(1.5);
+  }
+}
+static method g2(self::C<core::Object> c) → void {
+  c.f<core::num>(1.5);
+}
+static method test() → void {
+  new self::C::•<core::int>().g1<core::num>();
+  self::g2(new self::C::•<core::int>());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
new file mode 100644
index 0000000..f17aa36
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<generic-covariant-impl generic-covariant-interface U extends self::C::T>(self::C::f::U x) → void {}
+  method g1<generic-covariant-impl generic-covariant-interface U extends self::C::T>() → void {
+    this.{self::C::f}<self::C::g1::U>(let final core::double #t1 = 1.5 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks/covariant_generic_method_type_parameter.dart:11:35: Error: A value of type 'dart.core::double' can't be assigned to a variable of type 'test::C::g1::U'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::C::g1::U'.
+    this.f<U> /*@callKind=this*/ (1.5);
+                                  ^");
+  }
+}
+static method g2(self::C<core::Object> c) → void {
+  c.{self::C::f}<core::num>(1.5);
+}
+static method test() → void {
+  new self::C::•<core::int>().{self::C::g1}<core::num>();
+  self::g2(new self::C::•<core::int>());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.direct.transformed.expect
new file mode 100644
index 0000000..421712c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(self::C::T x) → void {}
+}
+static method g1(self::C<core::num> c) → void {
+  c.f(1.5);
+}
+static method g2(self::C<core::int> c) → void {
+  c.f(1);
+}
+static method g3(self::C<core::num> c) → void {
+  c.f(null);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.strong.transformed.expect
new file mode 100644
index 0000000..78f2e36
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(generic-covariant-impl generic-covariant-interface self::C::T x) → void {}
+}
+static method g1(self::C<core::num> c) → void {
+  c.{self::C::f}(1.5);
+}
+static method g2(self::C<core::int> c) → void {
+  c.{self::C::f}(1);
+}
+static method g3(self::C<core::num> c) → void {
+  c.{self::C::f}(null);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.direct.transformed.expect
new file mode 100644
index 0000000..51f994d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.direct.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1(core::List<self::C::T> x) → void {}
+  method f2(() → self::C::T callback) → void {}
+  method f3((self::C::T) → self::C::T callback) → void {}
+  method f4((self::C::T) → void callback) → void {}
+}
+static method g1(self::C<core::num> c, core::List<core::num> l) → void {
+  c.f1(l);
+}
+static method g2(self::C<core::num> c, () → core::num callback) → void {
+  c.f2(callback);
+}
+static method g3(self::C<core::num> c, (core::num) → core::num callback) → void {
+  c.f3(callback);
+}
+static method g4(self::C<core::num> c, (core::num) → void callback) → void {
+  c.f4(callback);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.strong.transformed.expect
new file mode 100644
index 0000000..e945744
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_complex.dart.strong.transformed.expect
@@ -0,0 +1,26 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1(generic-covariant-impl generic-covariant-interface core::List<self::C::T> x) → void {}
+  method f2(generic-covariant-impl generic-covariant-interface () → self::C::T callback) → void {}
+  method f3(generic-covariant-impl generic-covariant-interface (self::C::T) → self::C::T callback) → void {}
+  method f4((self::C::T) → void callback) → void {}
+}
+static method g1(self::C<core::num> c, core::List<core::num> l) → void {
+  c.{self::C::f1}(l);
+}
+static method g2(self::C<core::num> c, () → core::num callback) → void {
+  c.{self::C::f2}(callback);
+}
+static method g3(self::C<core::num> c, (core::num) → core::num callback) → void {
+  c.{self::C::f3}(callback);
+}
+static method g4(self::C<core::num> c, (core::num) → void callback) → void {
+  c.{self::C::f4}(callback);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.direct.transformed.expect
new file mode 100644
index 0000000..49169f4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.direct.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f1(self::I::T x) → void;
+  abstract method f2(self::I::T x) → void;
+}
+class C<U extends core::Object> extends core::Object implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1(core::int x) → void {}
+  method f2(core::int x, [self::C::U y = null]) → void {}
+}
+class D<U extends core::Object> extends self::C<self::D::U> {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f1(core::int x) → void {}
+  method f2(core::int x, [self::D::U y = null]) → void {}
+}
+static method g1(self::C<core::num> c) → void {
+  c.f1(1);
+}
+static method g2(self::I<core::num> i) → void {
+  i.f1(1.5);
+}
+static method g3(self::C<core::num> c) → void {
+  c.f2(1, 1.5);
+}
+static method g4(self::D<core::num> d) → void {
+  d.f1(1);
+}
+static method g5(self::D<core::num> d) → void {
+  d.f2(1, 1.5);
+}
+static method test() → void {
+  self::g2(new self::C::•<core::num>());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.strong.transformed.expect
new file mode 100644
index 0000000..b941549
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface.dart.strong.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f1(generic-covariant-impl generic-covariant-interface self::I::T x) → void;
+  abstract method f2(generic-covariant-impl generic-covariant-interface self::I::T x) → void;
+}
+class C<U extends core::Object> extends core::Object implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1(generic-covariant-impl core::int x) → void {}
+  method f2(generic-covariant-impl core::int x, [generic-covariant-impl generic-covariant-interface self::C::U y = null]) → void {}
+}
+class D<U extends core::Object> extends self::C<self::D::U> {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f1(generic-covariant-impl core::int x) → void {}
+  method f2(generic-covariant-impl core::int x, [generic-covariant-impl generic-covariant-interface self::D::U y = null]) → void {}
+}
+static method g1(self::C<core::num> c) → void {
+  c.{self::C::f1}(1);
+}
+static method g2(self::I<core::num> i) → void {
+  i.{self::I::f1}(1.5);
+}
+static method g3(self::C<core::num> c) → void {
+  c.{self::C::f2}(1, 1.5);
+}
+static method g4(self::D<core::num> d) → void {
+  d.{self::D::f1}(1);
+}
+static method g5(self::D<core::num> d) → void {
+  d.{self::D::f2}(1, 1.5);
+}
+static method test() → void {
+  self::g2(new self::C::•<core::num>());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.direct.transformed.expect
new file mode 100644
index 0000000..0292b5f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.direct.transformed.expect
@@ -0,0 +1,38 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(self::I::T x) → void;
+}
+class M extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → void {}
+}
+class C extends self::B implements self::I<core::int>, self::M {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  method f(core::int x) → void {}
+}
+static method g1(self::C c) → void {
+  c.f(1);
+}
+static method g2(self::I<core::num> i) → void {
+  i.f(1.5);
+}
+static method test() → void {
+  self::g2(new self::C::•());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.strong.transformed.expect
new file mode 100644
index 0000000..2a932d4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_mixin.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(generic-covariant-impl generic-covariant-interface self::I::T x) → void;
+}
+class M extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → void {}
+}
+class C extends self::B implements self::I<core::int>, self::M {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  method f(generic-covariant-impl core::int x) → void {}
+}
+static method g1(self::C c) → void {
+  c.{self::M::f}(1);
+}
+static method g2(self::I<core::num> i) → void {
+  i.{self::I::f}(1.5);
+}
+static method test() → void {
+  self::g2(new self::C::•());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.direct.transformed.expect
new file mode 100644
index 0000000..e6d6b9b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.direct.transformed.expect
@@ -0,0 +1,31 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(self::I::T x) → void;
+}
+class C extends self::B implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method g1(self::C c) → void {
+  c.f(1);
+}
+static method g2(self::I<core::num> i) → void {
+  i.f(1.5);
+}
+static method test() → void {
+  self::g2(new self::C::•());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.strong.transformed.expect
new file mode 100644
index 0000000..dfe595c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(generic-covariant-impl generic-covariant-interface self::I::T x) → void;
+}
+class C extends self::B implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  forwarding-stub method f(generic-covariant-impl core::int x) → void
+    return super.{self::B::f}(x);
+}
+static method g1(self::C c) → void {
+  c.{self::C::f}(1);
+}
+static method g2(self::I<core::num> i) → void {
+  i.{self::I::f}(1.5);
+}
+static method test() → void {
+  self::g2(new self::C::•());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.direct.transformed.expect
new file mode 100644
index 0000000..11b38c7
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.direct.transformed.expect
@@ -0,0 +1,36 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(self::I::T x) → void;
+}
+class M extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends self::B implements self::I<core::int>, self::M {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method g1(self::C c) → void {
+  c.f(1);
+}
+static method g2(self::I<core::num> i) → void {
+  i.f(1.5);
+}
+static method test() → void {
+  self::g2(new self::C::•());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.strong.transformed.expect
new file mode 100644
index 0000000..e10a6c4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_in_interface_super_mixin.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(generic-covariant-impl generic-covariant-interface self::I::T x) → void;
+}
+class M extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends self::B implements self::I<core::int>, self::M {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  forwarding-stub method f(generic-covariant-impl core::int x) → void
+    return super.{self::B::f}(x);
+}
+static method g1(self::C c) → void {
+  c.{self::B::f}(1);
+}
+static method g2(self::I<core::num> i) → void {
+  i.{self::I::f}(1.5);
+}
+static method test() → void {
+  self::g2(new self::C::•());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.direct.transformed.expect
new file mode 100644
index 0000000..f7ef8a8
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.direct.transformed.expect
@@ -0,0 +1,30 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+typedef G<T extends core::Object, U extends core::Object> = (T) → U;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1(self::C::T x) → void {}
+  method f2(core::List<self::C::T> x) → self::C::T
+    return x.first;
+}
+static method g1(self::C<core::num> c) → (core::num) → void {
+  return c.f1;
+}
+static method g2(self::C<core::int> c, core::Object x) → void {
+  (core::Object) → void f = self::g1(c) as (core::Object) → void;
+  f.call(x);
+}
+static method g3(self::C<core::num> c) → (core::List<core::num>) → core::num {
+  return c.f2;
+}
+static method test() → void {
+  dynamic x = self::g1(new self::C::•<core::int>());
+  x.call(1.5);
+  self::g3(new self::C::•<core::int>());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.transformed.expect
new file mode 100644
index 0000000..89e8e41
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_generic_parameter_tear_off.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+typedef G<T extends core::Object, U extends core::Object> = (T) → U;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1(generic-covariant-impl generic-covariant-interface self::C::T x) → void {}
+  method f2(generic-covariant-impl generic-covariant-interface core::List<self::C::T> x) → self::C::T
+    return x.{core::Iterable::first};
+}
+static method g1(self::C<core::num> c) → (core::num) → void {
+  return c.{self::C::f1};
+}
+static method g2(self::C<core::int> c, core::Object x) → void {
+  (core::Object) → void f = self::g1(c) as (core::Object) → void;
+  f.call(x);
+}
+static method g3(self::C<core::num> c) → (core::List<core::num>) → core::num {
+  return c.{self::C::f2};
+}
+static method test() → void {
+  (core::num) → void x = self::g1(new self::C::•<core::int>());
+  x.call(1.5);
+  self::g3(new self::C::•<core::int>());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.direct.transformed.expect
new file mode 100644
index 0000000..773f079
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.direct.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → dynamic;
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::num x) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f(covariant core::int x) → void {}
+}
+class E extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method f(core::int x) → void {}
+}
+static method g1(self::C c) → void {
+  c.f(1.5);
+}
+static method g2(self::C c) → (core::num) → dynamic {
+  return c.f;
+}
+static method test() → dynamic {
+  self::g1(new self::D::•());
+  (core::num) → dynamic x = self::g2(new self::D::•());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.transformed.expect
new file mode 100644
index 0000000..03b5829
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword.dart.strong.transformed.expect
@@ -0,0 +1,34 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → dynamic;
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::num x) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f(covariant core::int x) → void {}
+}
+class E extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method f(covariant core::int x) → void {}
+}
+static method g1(self::C c) → void {
+  c.{self::C::f}(1.5);
+}
+static method g2(self::C c) → (core::num) → dynamic {
+  return c.{self::C::f};
+}
+static method test() → dynamic {
+  self::g1(new self::D::•());
+  (core::num) → dynamic x = self::g2(new self::D::•());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..a100ec5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::num x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object implements self::C {
+  covariant field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object implements self::D {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..3c842e9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::num x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object implements self::C {
+  covariant field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object implements self::D {
+  covariant field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..61c27ca
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::num x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object implements self::C {
+  covariant field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object implements self::D {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+  set x(core::int value) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..0ec77c4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_field_inherited_by_setter.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::num x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object implements self::C {
+  covariant field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object implements self::D {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 0;
+  set x(covariant core::int value) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..fc4bc15
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::num value) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set x(covariant core::int value) → void {}
+}
+class E extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  set x(core::int value) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..ef38d7a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::num value) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set x(covariant core::int value) → void {}
+}
+class E extends self::D {
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  set x(covariant core::int value) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..dc7f644
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::num value) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set x(covariant core::int value) → void {}
+}
+class E extends core::Object implements self::D {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..8175f23
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_keyword_setter_inherited_by_field.dart.strong.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::num value) → void {}
+}
+class D extends self::C {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set x(covariant core::int value) → void {}
+}
+class E extends core::Object implements self::D {
+  covariant field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..3552fdc
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  field self::C::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set y(self::C::T value) → void {}
+  method f(self::C::T value) → void {
+    this.{self::C::x} = value;
+    this.{self::C::y} = value;
+  }
+}
+static method g(self::C<core::num> c) → void {
+  c.x = 1.5;
+  c.y = 1.5;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..6dcd2b4
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/covariant_setter.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set y(generic-covariant-impl generic-covariant-interface self::C::T value) → void {}
+  method f(generic-covariant-impl generic-covariant-interface self::C::T value) → void {
+    this.{self::C::x} = value;
+    this.{self::C::y} = value;
+  }
+}
+static method g(self::C<core::num> c) → void {
+  c.{self::C::x} = 1.5;
+  c.{self::C::y} = 1.5;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.direct.transformed.expect
new file mode 100644
index 0000000..e710937
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.direct.transformed.expect
@@ -0,0 +1,29 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1(self::C::T x) → void {}
+  method f2(core::int x) → void {}
+}
+class D extends self::C<core::num> {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f1(covariant core::int x) → void {}
+}
+static method g1(dynamic d) → void {
+  d.f1(1.5);
+}
+static method g2(dynamic d) → void {
+  d.f2(1.5);
+}
+static method test() → void {
+  self::g1(new self::C::•<core::int>());
+  self::g2(new self::C::•<dynamic>());
+  self::g1(new self::D::•());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.strong.transformed.expect
new file mode 100644
index 0000000..4655e62
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation.dart.strong.transformed.expect
@@ -0,0 +1,29 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f1(generic-covariant-impl generic-covariant-interface self::C::T x) → void {}
+  method f2(core::int x) → void {}
+}
+class D extends self::C<core::num> {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f1(covariant generic-covariant-impl core::int x) → void {}
+}
+static method g1(dynamic d) → void {
+  d.f1(1.5);
+}
+static method g2(dynamic d) → void {
+  d.f2(1.5);
+}
+static method test() → void {
+  self::g1(new self::C::•<core::int>());
+  self::g2(new self::C::•<dynamic>());
+  self::g1(new self::D::•());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.direct.transformed.expect
new file mode 100644
index 0000000..1bd3bd3
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.direct.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<U extends self::C::T>(self::C::f::U x) → void {}
+}
+static method g1(dynamic d) → void {
+  d.f<core::num>(1.5);
+}
+static method g2(dynamic d) → void {
+  d.f(1.5);
+}
+static method test() → void {
+  self::g1(new self::C::•<core::int>());
+  self::g2(new self::C::•<core::int>());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect
new file mode 100644
index 0000000..3ebc69c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_generic.dart.strong.transformed.expect
@@ -0,0 +1,21 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f<generic-covariant-impl generic-covariant-interface U extends self::C::T>(self::C::f::U x) → void {}
+}
+static method g1(dynamic d) → void {
+  d.f<core::num>(1.5);
+}
+static method g2(dynamic d) → void {
+  d.f(1.5);
+}
+static method test() → void {
+  self::g1(new self::C::•<core::int>());
+  self::g2(new self::C::•<core::int>());
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.direct.transformed.expect
new file mode 100644
index 0000000..5441e5e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic f;
+  constructor •(dynamic f) → void
+    : self::C::f = f, super core::Object::•()
+    ;
+}
+static method g(self::C c) → void {
+  c.f(1.5);
+}
+static method h(core::int i) → void {}
+static method test() → void {
+  self::g(new self::C::•(self::h));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.strong.transformed.expect
new file mode 100644
index 0000000..f2325b6
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/dynamic_invocation_of_getter.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic f;
+  constructor •(dynamic f) → void
+    : self::C::f = f, super core::Object::•()
+    ;
+}
+static method g(self::C c) → void {
+  c.{self::C::f}(1.5);
+}
+static method h(core::int i) → void {}
+static method test() → void {
+  self::g(new self::C::•(self::h));
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.direct.transformed.expect
new file mode 100644
index 0000000..bd9af0e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  field self::B::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field core::num x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C implements self::B<core::num> {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.strong.transformed.expect
new file mode 100644
index 0000000..0620b1b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/field_forwarding_stub_generic_covariant.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::B::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field core::num x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C implements self::B<core::num> {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  forwarding-stub set x(generic-covariant-impl core::num _) → void
+    return super.{self::C::x} = _;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.direct.transformed.expect
new file mode 100644
index 0000000..e6905e8
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.direct.transformed.expect
@@ -0,0 +1,40 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  field core::Object _x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f([core::num x = 10]) → void {
+    this.{self::B::_x} = x;
+  }
+  method g({core::num x = 20}) → void {
+    this.{self::B::_x} = x;
+  }
+  method check(core::Object expectedValue) → void {
+    if(!this.{self::B::_x}.==(expectedValue)) {
+      throw "Expected _x == ${expectedValue}; got ${this.{self::B::_x}}";
+    }
+  }
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f([self::I::T x = null]) → void;
+  abstract method g({self::I::T x = null}) → void;
+}
+class C extends self::B implements self::I<core::num> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → dynamic {
+  self::C c = new self::C::•();
+  c.f();
+  c.check(10);
+  c.g();
+  c.check(20);
+}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.transformed.expect
new file mode 100644
index 0000000..8db2e73
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_default_values.dart.strong.transformed.expect
@@ -0,0 +1,44 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  field core::Object _x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f([core::num x = 10]) → void {
+    this.{self::B::_x} = x;
+  }
+  method g({core::num x = 20}) → void {
+    this.{self::B::_x} = x;
+  }
+  method check(core::Object expectedValue) → void {
+    if(!this.{self::B::_x}.{core::Object::==}(expectedValue)) {
+      throw "Expected _x == ${expectedValue}; got ${this.{self::B::_x}}";
+    }
+  }
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f([generic-covariant-impl generic-covariant-interface self::I::T x = null]) → void;
+  abstract method g({generic-covariant-impl generic-covariant-interface self::I::T x = null}) → void;
+}
+class C extends self::B implements self::I<core::num> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  forwarding-stub method f([generic-covariant-impl core::num x]) → void
+    return super.{self::B::f}(x);
+  forwarding-stub method g({generic-covariant-impl core::num x}) → void
+    return super.{self::B::g}(x: x);
+}
+static method main() → dynamic {
+  self::C c = new self::C::•();
+  c.{self::C::f}();
+  c.{self::B::check}(10);
+  c.{self::C::g}();
+  c.{self::B::check}(20);
+}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.direct.transformed.expect
new file mode 100644
index 0000000..bc78480
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x, core::int y) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(self::I::T x, core::int y) → void;
+}
+class C extends self::B implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.strong.transformed.expect
new file mode 100644
index 0000000..0bfc9ad
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/forwarding_stub_with_non_covariant_param.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x, core::int y) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(generic-covariant-impl generic-covariant-interface self::I::T x, core::int y) → void;
+}
+class C extends self::B implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  forwarding-stub method f(generic-covariant-impl core::int x, core::int y) → void
+    return super.{self::B::f}(x, y);
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..e76c032
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.direct.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  field self::C::T y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(self::C::T t) → void {}
+}
+class D extends core::Object implements self::C<core::num> {
+  field core::num x = null;
+  field core::num y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object implements self::C<core::num> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(core::num t) → void {}
+  get y() → core::num
+    return null;
+  set y(core::num t) → void {}
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..42d0664
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_covariance_inheritance_setter_field.dart.strong.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::C::T y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(generic-covariant-impl generic-covariant-interface self::C::T t) → void {}
+}
+class D extends core::Object implements self::C<core::num> {
+  generic-covariant-impl field core::num x = null;
+  generic-covariant-impl field core::num y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class E extends core::Object implements self::C<core::num> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  set x(generic-covariant-impl core::num t) → void {}
+  get y() → core::num
+    return null;
+  set y(generic-covariant-impl core::num t) → void {}
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.direct.transformed.expect
new file mode 100644
index 0000000..6c33166
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.direct.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(covariant core::Object value) → void;
+}
+class B extends core::Object implements self::A {
+  field core::Object x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(covariant core::Object x) → void {}
+}
+class C<T extends core::Object> extends core::Object implements self::B {
+  field self::C::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(self::C::T x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.strong.transformed.expect
new file mode 100644
index 0000000..3cb3cc3
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/generic_vs_explicit_covariance.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(covariant core::Object value) → void;
+}
+class B extends core::Object implements self::A {
+  covariant field core::Object x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(covariant core::Object x) → void {}
+}
+class C<T extends core::Object> extends core::Object implements self::B {
+  covariant generic-covariant-impl generic-covariant-interface field self::C::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(covariant generic-covariant-impl generic-covariant-interface self::C::T x) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.direct.transformed.expect
new file mode 100644
index 0000000..c72d8754
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.direct.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •(core::Object o) → void
+    : assert(o), super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    new self::C::•(o);
+    assert(false, "no exception");
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.strong.transformed.expect
new file mode 100644
index 0000000..7d2a4f1
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_initializer.dart.strong.transformed.expect
@@ -0,0 +1,18 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  constructor •(core::Object o) → void
+    : assert(o as{TypeError} core::bool), super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    new self::C::•(o);
+    assert(false, "no exception");
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.direct.transformed.expect
new file mode 100644
index 0000000..c773ddb
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    assert(o);
+    assert(false, "no exception");
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.strong.transformed.expect
new file mode 100644
index 0000000..00b7aeb
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_assert_statement.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    assert(o as{TypeError} core::bool);
+    assert(false, "no exception");
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.direct.transformed.expect
new file mode 100644
index 0000000..d28fd17
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.direct.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::bool b;
+  constructor •(core::Object o) → void
+    : self::C::b = o, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    new self::C::•(o);
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.strong.transformed.expect
new file mode 100644
index 0000000..a47dcde
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_constructor_initializer.dart.strong.transformed.expect
@@ -0,0 +1,19 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field core::bool b;
+  constructor •(core::Object o) → void
+    : self::C::b = o as{TypeError} core::bool, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    new self::C::•(o);
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.direct.transformed.expect
new file mode 100644
index 0000000..5601fbc
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    do {
+    }
+    while (o)
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.strong.transformed.expect
new file mode 100644
index 0000000..675bb70
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_do.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    do {
+    }
+    while (o as{TypeError} core::bool)
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.direct.transformed.expect
new file mode 100644
index 0000000..4b976d7
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → void {
+  core::Object o = 1;
+  try {
+    for (core::int i = 0; o; i = i.+(1)) {
+    }
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.strong.transformed.expect
new file mode 100644
index 0000000..4689743
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_for_condition.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → void {
+  core::Object o = 1;
+  try {
+    for (core::int i = 0; o as{TypeError} core::bool; i = i.{core::num::+}(1)) {
+    }
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.direct.transformed.expect
new file mode 100644
index 0000000..9178d2a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    if(o) {
+    }
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.strong.transformed.expect
new file mode 100644
index 0000000..3b1beed
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_if.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    if(o as{TypeError} core::bool) {
+    }
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.direct.transformed.expect
new file mode 100644
index 0000000..5278cf9
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → void {
+  core::Object o = 1;
+  try {
+    !o;
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.strong.transformed.expect
new file mode 100644
index 0000000..e60450a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_not.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → void {
+  core::Object o = 1;
+  try {
+    !(o as{TypeError} core::bool);
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.direct.transformed.expect
new file mode 100644
index 0000000..2f67581
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.direct.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    while (o) {
+    }
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.strong.transformed.expect
new file mode 100644
index 0000000..70f751d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks/implicit_downcast_while.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+static method main() → dynamic {
+  core::Object o = 1;
+  try {
+    while (o as{TypeError} core::bool) {
+    }
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.direct.transformed.expect
new file mode 100644
index 0000000..fa00c10
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::num x) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(self::I::T x) → void;
+}
+class C extends self::B implements self::I<core::num> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  abstract method f(core::num x) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.strong.transformed.expect
new file mode 100644
index 0000000..4cdc473
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::num x) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(generic-covariant-impl generic-covariant-interface self::I::T x) → void;
+}
+class C extends self::B implements self::I<core::num> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  forwarding-stub forwarding-semi-stub method f(generic-covariant-impl core::num x) → void
+    return super.{self::B::f}(x);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.direct.transformed.expect
new file mode 100644
index 0000000..b0e9bfc
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.direct.transformed.expect
@@ -0,0 +1,39 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → dynamic;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(self::C::T x) → void {}
+  method g1(self::C::T x) → void {
+    this.{self::C::f}(x);
+  }
+  method g2(self::C::T x) → void {
+    this.{self::C::f}(x);
+  }
+  method g3(self::C<self::C::T> c, self::C::T x) → void {
+    c.f(x);
+  }
+  method g4() → (self::C::T) → dynamic
+    return this.{self::C::f};
+}
+class D extends self::C<core::int> {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+class E extends self::C<core::num> {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f(covariant core::int x) → void {}
+}
+static method test() → dynamic {
+  dynamic x = new self::D::•().g4() as (core::Object) → dynamic;
+  x.call("hi");
+  new self::E::•().g1(1.5);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.transformed.expect
new file mode 100644
index 0000000..1a496c8
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/call_through_this.dart.strong.transformed.expect
@@ -0,0 +1,48 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → dynamic;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(generic-covariant-impl generic-covariant-interface self::C::T x) → void {}
+  method g1(generic-covariant-impl generic-covariant-interface self::C::T x) → void {
+    this.{self::C::f}(x);
+  }
+  method g2(generic-covariant-impl generic-covariant-interface self::C::T x) → void {
+    this.{self::C::f}(x);
+  }
+  method g3(generic-covariant-impl generic-covariant-interface self::C<self::C::T> c, generic-covariant-impl generic-covariant-interface self::C::T x) → void {
+    c.{self::C::f}(x);
+  }
+  generic-contravariant method g4() → (self::C::T) → dynamic
+    return this.{self::C::f};
+}
+class D extends self::C<core::int> {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  abstract forwarding-stub method f(generic-covariant-impl core::int x) → void;
+  abstract forwarding-stub method g1(generic-covariant-impl core::int x) → void;
+  abstract forwarding-stub method g2(generic-covariant-impl core::int x) → void;
+  abstract forwarding-stub method g4() → (core::int) → dynamic;
+  abstract forwarding-stub method g3(generic-covariant-impl self::C<core::int> c, generic-covariant-impl core::int x) → void;
+}
+class E extends self::C<core::num> {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  method f(covariant generic-covariant-impl core::int x) → void {}
+  abstract forwarding-stub method g1(generic-covariant-impl core::num x) → void;
+  abstract forwarding-stub method g2(generic-covariant-impl core::num x) → void;
+  abstract forwarding-stub method g4() → (core::num) → dynamic;
+  abstract forwarding-stub method g3(generic-covariant-impl self::C<core::num> c, generic-covariant-impl core::num x) → void;
+}
+static method test() → dynamic {
+  (core::Object) → dynamic x = new self::D::•().{self::D::g4}() as (core::Object) → dynamic;
+  x.call("hi");
+  new self::E::•().{self::E::g1}(1.5);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.direct.transformed.expect
new file mode 100644
index 0000000..142da81
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.direct.transformed.expect
@@ -0,0 +1,39 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class B<T extends core::Object, U extends (self::B::T) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(dynamic other) → self::B<self::B::T, (self::B::T) → void>
+    return null;
+}
+class C extends core::Object {
+  field self::B<core::num, (core::num) → void> x = null;
+  static field self::B<core::num, (core::num) → void> y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int i) → self::B<core::num, (core::num) → void>
+    return null;
+  operator []=(core::int i, self::B<core::num, (core::num) → void> v) → void {}
+}
+static method test1(self::B<core::num, (core::num) → void> b) → void {
+  b = b.+(1);
+  dynamic x = b = b.+(2);
+}
+static method test2(self::C c) → void {
+  let final dynamic #t1 = c in let final dynamic #t2 = 0 in #t1.[]=(#t2, #t1.[](#t2).+(1));
+  dynamic x = let final dynamic #t3 = c in let final dynamic #t4 = 0 in let final dynamic #t5 = #t3.[](#t4).+(2) in let final dynamic #t6 = #t3.[]=(#t4, #t5) in #t5;
+}
+static method test3(self::C c) → void {
+  let final dynamic #t7 = c in #t7.x = #t7.x.+(1);
+  dynamic x = let final dynamic #t8 = c in #t8.x = #t8.x.+(2);
+}
+static method test4(self::C c) → void {
+  self::C::y = self::C::y.+(1);
+  dynamic x = self::C::y = self::C::y.+(2);
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.transformed.expect
new file mode 100644
index 0000000..0449783
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_combiner.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class B<T extends core::Object, U extends (self::B::T) → void> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  generic-contravariant operator +(dynamic other) → self::B<self::B::T, (self::B::T) → void>
+    return null;
+}
+class C extends core::Object {
+  field self::B<core::num, (core::num) → void> x = null;
+  static field self::B<core::num, (core::num) → void> y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int i) → self::B<core::num, (core::num) → void>
+    return null;
+  operator []=(core::int i, self::B<core::num, (core::num) → void> v) → void {}
+}
+static method test1(self::B<core::num, (core::num) → void> b) → void {
+  b = b.{self::B::+}(1) as{TypeError} self::B<core::num, (core::num) → void>;
+  self::B<core::num, (core::num) → void> x = b = b.{self::B::+}(2) as{TypeError} self::B<core::num, (core::num) → void>;
+}
+static method test2(self::C c) → void {
+  let final self::C #t1 = c in let final core::int #t2 = 0 in #t1.{self::C::[]=}(#t2, #t1.{self::C::[]}(#t2).{self::B::+}(1) as{TypeError} self::B<core::num, (core::num) → void>);
+  self::B<core::num, (core::num) → void> x = let final self::C #t3 = c in let final core::int #t4 = 0 in let final self::B<core::num, (core::num) → void> #t5 = #t3.{self::C::[]}(#t4).{self::B::+}(2) as{TypeError} self::B<core::num, (core::num) → void> in let final void #t6 = #t3.{self::C::[]=}(#t4, #t5) in #t5;
+}
+static method test3(self::C c) → void {
+  let final self::C #t7 = c in #t7.{self::C::x} = #t7.{self::C::x}.{self::B::+}(1) as{TypeError} self::B<core::num, (core::num) → void>;
+  self::B<core::num, (core::num) → void> x = let final self::C #t8 = c in #t8.{self::C::x} = #t8.{self::C::x}.{self::B::+}(2) as{TypeError} self::B<core::num, (core::num) → void>;
+}
+static method test4(self::C c) → void {
+  self::C::y = self::C::y.{self::B::+}(1) as{TypeError} self::B<core::num, (core::num) → void>;
+  self::B<core::num, (core::num) → void> x = self::C::y = self::C::y.{self::B::+}(2) as{TypeError} self::B<core::num, (core::num) → void>;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.direct.transformed.expect
new file mode 100644
index 0000000..f7da8fe
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.direct.transformed.expect
@@ -0,0 +1,51 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  final field (self::C::T) → core::num plusResult;
+  constructor •((self::C::T) → core::num plusResult) → void
+    : self::C::plusResult = plusResult, super core::Object::•()
+    ;
+  operator +(core::int i) → (self::C::T) → core::num
+    return this.{self::C::plusResult};
+}
+class D extends core::Object {
+  final field self::C<core::num> getValue;
+  field (core::int) → core::int setValue = null;
+  constructor •(self::C<core::num> getValue) → void
+    : self::D::getValue = getValue, super core::Object::•()
+    ;
+  get value() → self::C<core::num>
+    return this.{self::D::getValue};
+  set value((core::int) → core::int value) → void {
+    this.{self::D::setValue} = value;
+  }
+}
+static method expectTypeError(() → void callback) → void {
+  try {
+    callback.call();
+    throw "Expected TypeError, did not occur";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method expect(core::Object value, core::Object expected) → void {
+  if(!value.==(expected)) {
+    throw "Expected ${expected}, got ${value}";
+  }
+}
+static method numToInt(core::num n) → core::int
+  return 1;
+static method numToNum(core::num n) → core::num
+  return 2;
+static method main() → void {
+  self::D d = new self::D::•(new self::C::•<dynamic>(self::numToInt));
+  let final dynamic #t1 = d in #t1.value = #t1.value.+(1);
+  self::expect(d.setValue(0), 1);
+  d = new self::D::•(new self::C::•<dynamic>(self::numToNum));
+  self::expectTypeError(() → dynamic {
+    let final dynamic #t2 = d in #t2.value = #t2.value.+(1);
+  });
+  self::expect(d.setValue, null);
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
new file mode 100644
index 0000000..e07ce12
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart.strong.transformed.expect
@@ -0,0 +1,57 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  generic-contravariant final field (self::C::T) → core::num plusResult;
+  constructor •((self::C::T) → core::num plusResult) → void
+    : self::C::plusResult = plusResult, super core::Object::•()
+    ;
+  generic-contravariant operator +(core::int i) → (self::C::T) → core::num
+    return this.{self::C::plusResult};
+}
+class D extends core::Object {
+  final field self::C<core::num> getValue;
+  field (core::int) → core::int setValue = null;
+  constructor •(self::C<core::num> getValue) → void
+    : self::D::getValue = getValue, super core::Object::•()
+    ;
+  get value() → self::C<core::num>
+    return this.{self::D::getValue};
+  set value((core::int) → core::int value) → void {
+    this.{self::D::setValue} = value;
+  }
+}
+static method expectTypeError(() → void callback) → void {
+  try {
+    callback.call();
+    throw "Expected TypeError, did not occur";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method expect(core::Object value, core::Object expected) → void {
+  if(!value.{core::Object::==}(expected)) {
+    throw "Expected ${expected}, got ${value}";
+  }
+}
+static method numToInt(core::num n) → core::int
+  return 1;
+static method numToNum(core::num n) → core::num
+  return 2;
+static method main() → void {
+  self::D d = new self::D::•(new self::C::•<core::num>(self::numToInt));
+  let final self::D #t1 = d in #t1.{self::D::value} = let final (core::num) → core::num #t2 = #t1.{self::D::value}.{self::C::+}(1) as{TypeError} (core::num) → core::num in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:50:41: Error: A value of type '(dart.core::num) \u8594 dart.core::num' can't be assigned to a variable of type '(dart.core::int) \u8594 dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.core::int) \u8594 dart.core::int'.
+  d.value /*@checkReturn=(num) -> num*/ += 1;
+                                        ^";
+  self::expect(d.{self::D::setValue}(0), 1);
+  d = new self::D::•(new self::C::•<core::num>(self::numToNum));
+  self::expectTypeError(() → core::Null {
+    let final self::D #t3 = d in #t3.{self::D::value} = let final (core::num) → core::num #t4 = #t3.{self::D::value}.{self::C::+}(1) as{TypeError} (core::num) → core::num in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast.dart:54:43: Error: A value of type '(dart.core::num) \u8594 dart.core::num' can't be assigned to a variable of type '(dart.core::int) \u8594 dart.core::int'.
+Try changing the type of the left hand side, or casting the right hand side to '(dart.core::int) \u8594 dart.core::int'.
+    d.value /*@checkReturn=(num) -> num*/ += 1;
+                                          ^";
+  });
+  self::expect(d.{self::D::setValue}, null);
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.direct.transformed.expect
new file mode 100644
index 0000000..e5d0682
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(self::B<self::B::T> other) → self::B<self::B::T>
+    return null;
+}
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → self::B<(self::C::T) → void>
+    return null;
+  set x(self::B<(self::C::T) → void> value) → void {}
+}
+static method test(self::C<core::num> c) → void {
+  let final dynamic #t1 = c in #t1.x = #t1.x.+(new self::B::•<core::num>());
+  dynamic y = let final dynamic #t2 = c in #t2.x = #t2.x.+(new self::B::•<core::num>());
+  let final dynamic #t3 = c in #t3.x.==(null) ? #t3.x = new self::B::•<core::num>() : null;
+  dynamic z = let final dynamic #t4 = c in let final dynamic #t5 = #t4.x in #t5.==(null) ? #t4.x = new self::B::•<core::num>() : #t5;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
new file mode 100644
index 0000000..a61408f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart.strong.transformed.expect
@@ -0,0 +1,39 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(generic-covariant-impl generic-covariant-interface self::B<self::B::T> other) → self::B<self::B::T>
+    return null;
+}
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  generic-contravariant get x() → self::B<(self::C::T) → void>
+    return null;
+  set x(self::B<(self::C::T) → void> value) → void {}
+}
+static method test(self::C<core::num> c) → void {
+  let final self::C<core::num> #t1 = c in #t1.{self::C::x} = (#t1.{self::C::x} as{TypeError} self::B<(core::num) → void>).{self::B::+}(let final self::B<core::num> #t2 = new self::B::•<core::num>() in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:21:49: Error: A value of type 'test::B<dart.core::num>' can't be assigned to a variable of type 'test::B<(dart.core::num) \u8594 void>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::B<(dart.core::num) \u8594 void>'.
+  c. /*@checkReturn=B<(num) -> void>*/ x += new B<num>();
+                                                ^");
+  self::B<(core::num) → void> y = let final self::C<core::num> #t3 = c in #t3.{self::C::x} = (#t3.{self::C::x} as{TypeError} self::B<(core::num) → void>).{self::B::+}(let final self::B<core::num> #t4 = new self::B::•<core::num>() in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:22:57: Error: A value of type 'test::B<dart.core::num>' can't be assigned to a variable of type 'test::B<(dart.core::num) \u8594 void>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::B<(dart.core::num) \u8594 void>'.
+  var y = c. /*@checkReturn=B<(num) -> void>*/ x += new B<num>();
+                                                        ^");
+  let final self::C<core::num> #t5 = c in (#t5.{self::C::x} as{TypeError} self::B<(core::num) → void>).{core::Object::==}(null) ?{self::B<core::Object>} #t5.{self::C::x} = let final self::B<core::num> #t6 = new self::B::•<core::num>() in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:23:50: Error: A value of type 'test::B<dart.core::num>' can't be assigned to a variable of type 'test::B<(dart.core::num) \u8594 void>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::B<(dart.core::num) \u8594 void>'.
+  c. /*@checkReturn=B<(num) -> void>*/ x ??= new B<num>();
+                                                 ^" : null;
+  self::B<core::Object> z = let final self::C<core::num> #t7 = c in let final self::B<(core::num) → void> #t8 = #t7.{self::C::x} as{TypeError} self::B<(core::num) → void> in #t8.{core::Object::==}(null) ?{self::B<core::Object>} #t7.{self::C::x} = let final self::B<core::num> #t9 = new self::B::•<core::num>() in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/runtime_checks_new/contravariant_getter_return_compound_assign.dart:24:58: Error: A value of type 'test::B<dart.core::num>' can't be assigned to a variable of type 'test::B<(dart.core::num) \u8594 void>'.
+Try changing the type of the left hand side, or casting the right hand side to 'test::B<(dart.core::num) \u8594 void>'.
+  var z = c. /*@checkReturn=B<(num) -> void>*/ x ??= new B<num>();
+                                                         ^" : #t8;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.direct.transformed.expect
new file mode 100644
index 0000000..78a8669
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.direct.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(self::B<self::B::T> other) → self::B<self::B::T>
+    return null;
+}
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int i) → self::B<(self::C::T) → void>
+    return null;
+  operator []=(core::int i, self::B<(self::C::T) → void> x) → void {}
+}
+static method test(self::C<core::num> c) → void {
+  c.[]=(0, new self::B::•<(core::num) → void>());
+  let final dynamic #t1 = c in let final dynamic #t2 = 0 in #t1.[]=(#t2, #t1.[](#t2).+(new self::B::•<(core::num) → void>()));
+  dynamic x = let final dynamic #t3 = c in let final dynamic #t4 = 0 in let final dynamic #t5 = #t3.[](#t4).+(new self::B::•<(core::num) → void>()) in let final dynamic #t6 = #t3.[]=(#t4, #t5) in #t5;
+  let final dynamic #t7 = c in let final dynamic #t8 = 0 in #t7.[](#t8).==(null) ? let final dynamic #t9 = new self::B::•<(core::num) → void>() in let final dynamic #t10 = #t7.[]=(#t8, #t9) in #t9 : null;
+  dynamic y = let final dynamic #t11 = c in let final dynamic #t12 = 0 in let final dynamic #t13 = #t11.[](#t12) in #t13.==(null) ? let final dynamic #t14 = new self::B::•<(core::num) → void>() in let final dynamic #t15 = #t11.[]=(#t12, #t14) in #t14 : #t13;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect
new file mode 100644
index 0000000..74c67a7
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_assign.dart.strong.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator +(generic-covariant-impl generic-covariant-interface self::B<self::B::T> other) → self::B<self::B::T>
+    return null;
+}
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  generic-contravariant operator [](core::int i) → self::B<(self::C::T) → void>
+    return null;
+  operator []=(core::int i, self::B<(self::C::T) → void> x) → void {}
+}
+static method test(self::C<core::num> c) → void {
+  c.{self::C::[]=}(0, new self::B::•<(core::num) → void>());
+  let final self::C<core::num> #t1 = c in let final core::int #t2 = 0 in #t1.{self::C::[]=}(#t2, (#t1.{self::C::[]}(#t2) as{TypeError} self::B<(core::num) → void>).{self::B::+}(new self::B::•<(core::num) → void>()));
+  self::B<(core::num) → void> x = let final self::C<core::num> #t3 = c in let final core::int #t4 = 0 in let final self::B<(core::num) → void> #t5 = (#t3.{self::C::[]}(#t4) as{TypeError} self::B<(core::num) → void>).{self::B::+}(new self::B::•<(core::num) → void>()) in let final void #t6 = #t3.{self::C::[]=}(#t4, #t5) in #t5;
+  let final self::C<core::num> #t7 = c in let final core::int #t8 = 0 in (#t7.{self::C::[]}(#t8) as{TypeError} self::B<(core::num) → void>).{core::Object::==}(null) ?{self::B<(core::num) → void>} let final self::B<(core::num) → void> #t9 = new self::B::•<(core::num) → void>() in let final void #t10 = #t7.{self::C::[]=}(#t8, #t9) in #t9 : null;
+  self::B<(core::num) → void> y = let final self::C<core::num> #t11 = c in let final core::int #t12 = 0 in let final self::B<(core::num) → void> #t13 = #t11.{self::C::[]}(#t12) as{TypeError} self::B<(core::num) → void> in #t13.{core::Object::==}(null) ?{self::B<(core::num) → void>} let final self::B<(core::num) → void> #t14 = new self::B::•<(core::num) → void>() in let final void #t15 = #t11.{self::C::[]=}(#t12, #t14) in #t14 : #t13;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.direct.transformed.expect
new file mode 100644
index 0000000..02c5897
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  operator [](core::int i) → (self::C::T) → void
+    return null;
+}
+static method test(self::C<core::num> c) → (core::num) → void {
+  return c.[](0);
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.transformed.expect
new file mode 100644
index 0000000..5653b2b
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/contravariant_index_get.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  generic-contravariant operator [](core::int i) → (self::C::T) → void
+    return null;
+}
+static method test(self::C<core::num> c) → (core::num) → void {
+  return c.{self::C::[]}(0) as{TypeError} (core::num) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.direct.transformed.expect
new file mode 100644
index 0000000..e8eb073
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(self::B::T x) → void {}
+  method g({self::B::T x = null}) → void {}
+  method h<U extends self::B::T>() → void {}
+}
+class C extends self::B<core::int> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method g1(self::B<core::num> b) → void {
+  b.f(1.5);
+}
+static method g2(self::C c) → void {
+  c.f(1);
+}
+static method test() → void {
+  self::g1(new self::C::•());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect
new file mode 100644
index 0000000..e4bff7d
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/derived_class_typed.dart.strong.transformed.expect
@@ -0,0 +1,30 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(generic-covariant-impl generic-covariant-interface self::B::T x) → void {}
+  method g({generic-covariant-impl generic-covariant-interface self::B::T x = null}) → void {}
+  method h<generic-covariant-impl generic-covariant-interface U extends self::B::T>() → void {}
+}
+class C extends self::B<core::int> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  abstract forwarding-stub method f(generic-covariant-impl core::int x) → void;
+  abstract forwarding-stub method h<generic-covariant-impl U extends core::int>() → void;
+  abstract forwarding-stub method g({generic-covariant-impl core::int x}) → void;
+}
+static method g1(self::B<core::num> b) → void {
+  b.{self::B::f}(1.5);
+}
+static method g2(self::C c) → void {
+  c.{self::C::f}(1);
+}
+static method test() → void {
+  self::g1(new self::C::•());
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.direct.transformed.expect
new file mode 100644
index 0000000..5ae17d3
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  field self::B::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends self::B<core::num> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.strong.transformed.expect
new file mode 100644
index 0000000..e0ee96e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_abstract_generic_covariant.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::B::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends self::B<core::num> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  abstract forwarding-stub set x(generic-covariant-impl core::num _) → void;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.direct.transformed.expect
new file mode 100644
index 0000000..0825415
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  covariant field core::num x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C implements self::B {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.strong.transformed.expect
new file mode 100644
index 0000000..98aaa88
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/field_forwarding_stub_explicit_covariant.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  covariant field core::num x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  field core::int x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class D extends self::C implements self::B {
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  forwarding-stub set x(covariant core::num _) → void
+    return super.{self::C::x} = _;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.direct.transformed.expect
new file mode 100644
index 0000000..810f4b8
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.direct.transformed.expect
@@ -0,0 +1,40 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field dynamic staticField = null;
+  field dynamic instanceField = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static set staticSetter(dynamic x) → void {}
+  set instanceSetter(dynamic x) → void {}
+  method test() → void {
+    dynamic localVar;
+    for (final dynamic #t1 in <dynamic>[]) {
+      self::topLevel = #t1;
+    }
+    for (final dynamic #t2 in <dynamic>[]) {
+      self::topLevelSetter = #t2;
+    }
+    for (final dynamic #t3 in <dynamic>[]) {
+      self::C::staticField = #t3;
+    }
+    for (final dynamic #t4 in <dynamic>[]) {
+      self::C::staticSetter = #t4;
+    }
+    for (final dynamic #t5 in <dynamic>[]) {
+      this.{self::C::instanceField} = #t5;
+    }
+    for (final dynamic #t6 in <dynamic>[]) {
+      this.{self::C::instanceSetter} = #t6;
+    }
+    for (final dynamic #t7 in <dynamic>[]) {
+      localVar = #t7;
+    }
+  }
+}
+static field dynamic topLevel;
+static set topLevelSetter(dynamic x) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.strong.transformed.expect
new file mode 100644
index 0000000..810f4b8
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/for_in_call_kinds.dart.strong.transformed.expect
@@ -0,0 +1,40 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field dynamic staticField = null;
+  field dynamic instanceField = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  static set staticSetter(dynamic x) → void {}
+  set instanceSetter(dynamic x) → void {}
+  method test() → void {
+    dynamic localVar;
+    for (final dynamic #t1 in <dynamic>[]) {
+      self::topLevel = #t1;
+    }
+    for (final dynamic #t2 in <dynamic>[]) {
+      self::topLevelSetter = #t2;
+    }
+    for (final dynamic #t3 in <dynamic>[]) {
+      self::C::staticField = #t3;
+    }
+    for (final dynamic #t4 in <dynamic>[]) {
+      self::C::staticSetter = #t4;
+    }
+    for (final dynamic #t5 in <dynamic>[]) {
+      this.{self::C::instanceField} = #t5;
+    }
+    for (final dynamic #t6 in <dynamic>[]) {
+      this.{self::C::instanceSetter} = #t6;
+    }
+    for (final dynamic #t7 in <dynamic>[]) {
+      localVar = #t7;
+    }
+  }
+}
+static field dynamic topLevel;
+static set topLevelSetter(dynamic x) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.transformed.expect
new file mode 100644
index 0000000..a69ba21
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.direct.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  field self::B::T x = null;
+  field self::B::T y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<T extends core::Object> extends core::Object implements self::B<core::num> {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get y() → dynamic;
+  abstract set y(dynamic value) → dynamic;
+}
+class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get y() → dynamic;
+  abstract set y(dynamic value) → dynamic;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.transformed.expect
new file mode 100644
index 0000000..7a67ecc
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/generic_covariance_based_on_inference.dart.strong.transformed.expect
@@ -0,0 +1,28 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  generic-covariant-impl generic-covariant-interface field self::B::T x = null;
+  generic-covariant-impl generic-covariant-interface field self::B::T y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C<T extends core::Object> extends core::Object implements self::B<core::num> {
+  generic-covariant-impl field core::num x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get y() → core::num;
+  abstract set y(generic-covariant-impl core::num value) → void;
+}
+class D<T extends core::Object> extends core::Object implements self::B<self::D::T> {
+  generic-covariant-impl generic-covariant-interface field self::D::T x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get y() → self::D::T;
+  abstract set y(generic-covariant-impl generic-covariant-interface self::D::T value) → void;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..8e15a1f
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.direct.transformed.expect
@@ -0,0 +1,33 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::bool staticValue = self::o;
+  field core::bool instanceValue = self::o;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::Object o = 1;
+static field core::bool topLevelValue = self::o;
+static method main() → dynamic {
+  try {
+    self::topLevelValue;
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+  try {
+    self::C::staticValue;
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+  try {
+    new self::C::•();
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.strong.transformed.expect
new file mode 100644
index 0000000..8cea5b3
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/implicit_downcast_field.dart.strong.transformed.expect
@@ -0,0 +1,33 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  static field core::bool staticValue = self::o as{TypeError} core::bool;
+  field core::bool instanceValue = self::o as{TypeError} core::bool;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static field core::Object o = 1;
+static field core::bool topLevelValue = self::o as{TypeError} core::bool;
+static method main() → dynamic {
+  try {
+    self::topLevelValue;
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+  try {
+    self::C::staticValue;
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+  try {
+    new self::C::•();
+    throw "no exception";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.direct.transformed.expect
new file mode 100644
index 0000000..78ffd8c5
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_field.dart.direct.transformed.expect
@@ -0,0 +1,72 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int {
+    throw "Should not be reached";
+  }
+  set x(core::int value) → void {
+    throw "Should not be reached";
+  }
+  get y() → core::int {
+    throw "Should not be reached";
+  }
+  set y(core::int value) → void {
+    throw "Should not be reached";
+  }
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → self::I::T;
+  abstract set x(self::I::T value) → void;
+  abstract get y() → core::Object;
+  abstract set y(covariant core::Object value) → void;
+}
+class M extends core::Object {
+  field core::int x = null;
+  field core::int y = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class C extends self::B implements self::I<core::int>, self::M {
+  field core::int x = null;
+  field core::int y = null;
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method expectTypeError(() → void callback) → void {
+  try {
+    callback.call();
+    throw "Expected TypeError, did not occur";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method expect(core::Object value, core::Object expected) → void {
+  if(!value.==(expected)) {
+    throw "Expected ${expected}, got ${value}";
+  }
+}
+static method test(self::I<core::Object> i) → void {
+  self::expectTypeError(() → dynamic {
+    i.x = "hello";
+  });
+  i.x = 1;
+  self::expect(i.x, 1);
+  self::expectTypeError(() → dynamic {
+    i.y = "hello";
+  });
+  i.y = 2;
+  self::expect(i.y, 2);
+}
+static method main() → void {
+  self::test(new self::C::•());
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart.direct.transformed.expect
new file mode 100644
index 0000000..f43208c
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_getter.dart.direct.transformed.expect
@@ -0,0 +1,78 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → (core::int) → void {
+    throw "Should not be reached";
+  }
+  set x(core::Object value) → void {
+    throw "Should not be reached";
+  }
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → (self::I::T) → void;
+  abstract set x(core::Object value) → void;
+}
+abstract class M<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → self::M::T
+    return this.{self::M::f}();
+  set x(core::Object value) → void {
+    throw "Should not be reached";
+  }
+  abstract method f() → self::M::T;
+}
+abstract class C<T extends core::Object> extends self::B implements self::I<self::C::T>, self::M<(self::C::T) → void> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  get x() → (self::C::T) → void
+    return this.{self::M::f}();
+  set x(core::Object value) → void {
+    throw "Should not be reached";
+  }
+  abstract method f() → (self::C::T) → void;
+}
+class D extends self::C<core::int> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  method f() → (core::int) → void
+    return (core::int i) → dynamic {
+      self::expect(i, 1);
+    };
+}
+static method expectTypeError(() → void callback) → void {
+  try {
+    callback.call();
+    throw "Expected TypeError, did not occur";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method expect(core::Object value, core::Object expected) → void {
+  if(!value.==(expected)) {
+    throw "Expected ${expected}, got ${value}";
+  }
+}
+static method test(self::I<core::Object> iObj, self::I<core::int> iInt) → void {
+  self::expectTypeError(() → dynamic {
+    dynamic x = iObj.x;
+  });
+  dynamic x = iInt.x;
+  x.call(1);
+}
+static method main() → void {
+  dynamic d = new self::D::•();
+  self::test(d, d);
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..b204ff8
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/mixin_forwarding_stub_setter.dart.direct.transformed.expect
@@ -0,0 +1,88 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int {
+    throw "Should not be reached";
+  }
+  set x(core::int value) → void {
+    throw "Should not be reached";
+  }
+  get y() → core::int {
+    throw "Should not be reached";
+  }
+  set y(core::int value) → void {
+    throw "Should not be reached";
+  }
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract get x() → self::I::T;
+  abstract set x(self::I::T value) → void;
+  abstract get y() → core::Object;
+  abstract set y(covariant core::Object value) → void;
+}
+class M extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get x() → core::int
+    return 1;
+  set x(core::int value) → void {
+    self::expect(value, 2);
+  }
+  get y() → core::int
+    return 3;
+  set y(core::int value) → void {
+    self::expect(value, 4);
+  }
+}
+class C extends self::B implements self::I<core::int>, self::M {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  get x() → core::int
+    return 1;
+  set x(core::int value) → void {
+    self::expect(value, 2);
+  }
+  get y() → core::int
+    return 3;
+  set y(core::int value) → void {
+    self::expect(value, 4);
+  }
+}
+static method expectTypeError(() → void callback) → void {
+  try {
+    callback.call();
+    throw "Expected TypeError, did not occur";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method expect(core::Object value, core::Object expected) → void {
+  if(!value.==(expected)) {
+    throw "Expected ${expected}, got ${value}";
+  }
+}
+static method test(self::I<core::Object> i) → void {
+  self::expectTypeError(() → dynamic {
+    i.x = "hello";
+  });
+  i.x = 2;
+  self::expect(i.x, 1);
+  self::expectTypeError(() → dynamic {
+    i.y = "hello";
+  });
+  i.y = 4;
+  self::expect(i.y, 3);
+}
+static method main() → void {
+  self::test(new self::C::•());
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.direct.transformed.expect
new file mode 100644
index 0000000..b0a0022
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.direct.transformed.expect
@@ -0,0 +1,54 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → core::int {
+    self::expect(x, 1);
+    return 2;
+  }
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(covariant core::Object x) → core::int;
+}
+class C extends self::B implements self::I {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method expectTypeError(() → void callback) → void {
+  try {
+    callback.call();
+    throw "Expected TypeError, did not occur";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method expect(core::Object value, core::Object expected) → void {
+  if(!value.==(expected)) {
+    throw "Expected ${expected}, got ${value}";
+  }
+}
+static method g(self::C c) → void {
+  c.f("hello");
+}
+static method test(self::C c, self::I i) → void {
+  self::expectTypeError(() → dynamic {
+    i.f("hello");
+  });
+  self::expect(i.f(1), 2);
+  self::expectTypeError(() → dynamic {
+    c.f("hello");
+  });
+  self::expect(c.f(1), 2);
+}
+static method main() → dynamic {
+  dynamic c = new self::C::•();
+  self::test(c, c);
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.transformed.expect
new file mode 100644
index 0000000..33025a0
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_checked_via_target.dart.strong.transformed.expect
@@ -0,0 +1,56 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → core::int {
+    self::expect(x, 1);
+    return 2;
+  }
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(covariant core::Object x) → core::int;
+}
+class C extends self::B implements self::I {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  forwarding-stub method f(covariant core::Object x) → core::int
+    return super.{self::B::f}(x);
+}
+static method expectTypeError(() → void callback) → void {
+  try {
+    callback.call();
+    throw "Expected TypeError, did not occur";
+  }
+  on core::TypeError catch(no-exception-var) {
+  }
+}
+static method expect(core::Object value, core::Object expected) → void {
+  if(!value.{core::Object::==}(expected)) {
+    throw "Expected ${expected}, got ${value}";
+  }
+}
+static method g(self::C c) → void {
+  c.{self::C::f}("hello");
+}
+static method test(self::C c, self::I i) → void {
+  self::expectTypeError(() → core::Null {
+    i.{self::I::f}("hello");
+  });
+  self::expect(i.{self::I::f}(1), 2);
+  self::expectTypeError(() → core::Null {
+    c.{self::C::f}("hello");
+  });
+  self::expect(c.{self::C::f}(1), 2);
+}
+static method main() → dynamic {
+  self::C c = new self::C::•();
+  self::test(c, c);
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_contravariant_from_class.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_contravariant_from_class.dart.direct.transformed.expect
new file mode 100644
index 0000000..8324835
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_contravariant_from_class.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x) → self::B::T {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(core::Object x) → self::I::T;
+}
+class C<T extends core::Object> extends self::B<(self::C::T) → void> implements self::I<(self::C::T) → void> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_class.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_class.dart.direct.transformed.expect
new file mode 100644
index 0000000..1d29587
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_class.dart.direct.transformed.expect
@@ -0,0 +1,23 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f((self::B::T) → void x, core::int y) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f((self::I::T) → void x, core::Object y) → void;
+}
+class C<T extends core::Object> extends self::B<(self::C::T) → void> implements self::I<(self::C::T) → void> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_class.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_class.dart.strong.transformed.expect
new file mode 100644
index 0000000..ee19538
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_class.dart.strong.transformed.expect
@@ -0,0 +1,25 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f((self::B::T) → void x, core::int y) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f((self::I::T) → void x, core::Object y) → void;
+}
+class C<T extends core::Object> extends self::B<(self::C::T) → void> implements self::I<(self::C::T) → void> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  forwarding-stub method f(generic-covariant-impl generic-covariant-interface ((self::C::T) → void) → void x, core::Object y) → void
+    return super.{self::B::f}(x, y);
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.direct.transformed.expect
new file mode 100644
index 0000000..fcf58faa
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x, core::int y) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(self::I::T x, core::Object y) → void;
+}
+class C extends self::B implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.strong.transformed.expect
new file mode 100644
index 0000000..892c2f0
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_interface.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x, core::int y) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(generic-covariant-impl generic-covariant-interface self::I::T x, core::Object y) → void;
+}
+class C extends self::B implements self::I<core::int> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  forwarding-stub method f(generic-covariant-impl core::int x, core::Object y) → void
+    return super.{self::B::f}(x, y);
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.direct.transformed.expect
new file mode 100644
index 0000000..b2f0239
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantImpl_from_super.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(self::B::T x, core::int y) → void {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(core::int x, core::Object y) → void;
+}
+class C extends self::B<core::int> implements self::I {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantInterface_from_class.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantInterface_from_class.dart.direct.transformed.expect
new file mode 100644
index 0000000..a9dd532
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariantInterface_from_class.dart.direct.transformed.expect
@@ -0,0 +1,29 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+typedef F<T extends core::Object> = (T) → void;
+abstract class A<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(self::A::T x, core::int y) → void;
+}
+class B<T extends core::Object> extends core::Object implements self::A<(self::B::T) → void> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f((self::B::T) → void x, core::int y) → void {}
+}
+abstract class I<T extends core::Object> extends core::Object implements self::A<(self::I::T) → void> {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f((self::I::T) → void x, core::Object y) → void;
+}
+class C<T extends core::Object> extends self::B<(self::C::T) → void> implements self::I<(self::C::T) → void> {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.direct.transformed.expect
new file mode 100644
index 0000000..3b68eaf
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x, core::int y) → void {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(covariant core::int x, core::Object y) → void;
+}
+class C extends self::B implements self::I {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.strong.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.strong.transformed.expect
new file mode 100644
index 0000000..e6a169e
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_interface.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(core::int x, core::int y) → void {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(covariant core::int x, core::Object y) → void;
+}
+class C extends self::B implements self::I {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  forwarding-stub method f(covariant core::int x, core::Object y) → void
+    return super.{self::B::f}(x, y);
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.direct.transformed.expect b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.direct.transformed.expect
new file mode 100644
index 0000000..67e593a
--- /dev/null
+++ b/pkg/front_end/testcases/runtime_checks_new/stub_from_interface_covariant_from_super.dart.direct.transformed.expect
@@ -0,0 +1,22 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class B extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f(covariant core::int x, core::int y) → void {}
+}
+abstract class I extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method f(core::int x, core::Object y) → void;
+}
+class C extends self::B implements self::I {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+}
+static method main() → void {}
diff --git a/pkg/front_end/testcases/static_setter.dart.direct.transformed.expect b/pkg/front_end/testcases/static_setter.dart.direct.transformed.expect
new file mode 100644
index 0000000..cdb5c4d
--- /dev/null
+++ b/pkg/front_end/testcases/static_setter.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static set foo(dynamic x) → dynamic {}
+static method main() → dynamic {
+  self::foo = new self::Foo::•();
+}
diff --git a/pkg/front_end/testcases/static_setter.dart.strong.transformed.expect b/pkg/front_end/testcases/static_setter.dart.strong.transformed.expect
new file mode 100644
index 0000000..98e7239
--- /dev/null
+++ b/pkg/front_end/testcases/static_setter.dart.strong.transformed.expect
@@ -0,0 +1,13 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static set foo(dynamic x) → void {}
+static method main() → dynamic {
+  self::foo = new self::Foo::•();
+}
diff --git a/pkg/front_end/testcases/store_load.dart.direct.transformed.expect b/pkg/front_end/testcases/store_load.dart.direct.transformed.expect
new file mode 100644
index 0000000..ad7092d
--- /dev/null
+++ b/pkg/front_end/testcases/store_load.dart.direct.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic _field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class FooValue extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends core::Object {
+  field dynamic _field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class BarValue extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  dynamic foo = new self::Foo::•();
+  foo._field = new self::FooValue::•();
+  dynamic fooValue = foo._field;
+  core::print(fooValue);
+  dynamic bar = new self::Bar::•();
+  bar._field = new self::BarValue::•();
+  dynamic barValue = bar._field;
+  core::print(barValue);
+}
diff --git a/pkg/front_end/testcases/store_load.dart.strong.transformed.expect b/pkg/front_end/testcases/store_load.dart.strong.transformed.expect
new file mode 100644
index 0000000..59c3869
--- /dev/null
+++ b/pkg/front_end/testcases/store_load.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  field dynamic _field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class FooValue extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class Bar extends core::Object {
+  field dynamic _field = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class BarValue extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  self::Foo foo = new self::Foo::•();
+  foo.{self::Foo::_field} = new self::FooValue::•();
+  dynamic fooValue = foo.{self::Foo::_field};
+  core::print(fooValue);
+  self::Bar bar = new self::Bar::•();
+  bar.{self::Bar::_field} = new self::BarValue::•();
+  dynamic barValue = bar.{self::Bar::_field};
+  core::print(barValue);
+}
diff --git a/pkg/front_end/testcases/stringliteral.dart.direct.transformed.expect b/pkg/front_end/testcases/stringliteral.dart.direct.transformed.expect
new file mode 100644
index 0000000..ca4c0cb
--- /dev/null
+++ b/pkg/front_end/testcases/stringliteral.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+
+static field dynamic color = "brown";
+static field dynamic thing = "lazy dog";
+static field dynamic phrase = "The quick ${self::color} fox
+jumped over the ${self::thing}.
+";
+static field dynamic adjacent = "${self::color}${self::color}${self::color}";
+static field dynamic linebreaks = "${self::color}
+${self::color}
+${self::color}";
+static field dynamic other = "${self::color}
+ is 
+${self::color}";
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/super_call.dart.direct.transformed.expect b/pkg/front_end/testcases/super_call.dart.direct.transformed.expect
new file mode 100644
index 0000000..d97a5e2
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart.direct.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call(core::int x) → core::int
+    return x.*(2);
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  method call(core::int x) → core::int
+    return x.*(3);
+  method call_super() → core::int {
+    return invalid-expression "pkg/front_end/testcases/super_call.dart:14:12: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+    return super(5);
+           ^";
+  }
+}
+static method main() → dynamic {
+  assert(new self::B::•().call_super().==(10));
+}
diff --git a/pkg/front_end/testcases/super_call.dart.strong.transformed.expect b/pkg/front_end/testcases/super_call.dart.strong.transformed.expect
new file mode 100644
index 0000000..be03ad0
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method call(core::int x) → core::int
+    return x.{core::num::*}(2);
+}
+class B extends self::A {
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  method call(core::int x) → core::int
+    return x.{core::num::*}(3);
+  method call_super() → core::int {
+    return invalid-expression "pkg/front_end/testcases/super_call.dart:14:12: Error: Can't use 'super' as an expression.
+To delegate a constructor to a super constructor, put the super call as an initializer.
+    return super(5);
+           ^" as{TypeError} core::int;
+  }
+}
+static method main() → dynamic {
+  assert(new self::B::•().{self::B::call_super}().{core::num::==}(10));
+}
diff --git a/pkg/front_end/testcases/super_rasta_copy.dart.direct.transformed.expect b/pkg/front_end/testcases/super_rasta_copy.dart.direct.transformed.expect
new file mode 100644
index 0000000..eac205d
--- /dev/null
+++ b/pkg/front_end/testcases/super_rasta_copy.dart.direct.transformed.expect
@@ -0,0 +1,248 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  field dynamic a = null;
+  field dynamic b = null;
+  field dynamic c = null;
+  field dynamic d = null;
+  final field dynamic f = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  get e() → dynamic
+    return null;
+  set g(dynamic _) → dynamic {}
+  get h() → dynamic
+    return null;
+  set h(dynamic _) → dynamic {}
+  get i() → dynamic
+    return null;
+  operator [](dynamic _) → dynamic
+    return null;
+  operator []=(dynamic a, dynamic b) → dynamic {}
+  operator ~() → dynamic
+    return 117;
+  operator unary-() → dynamic
+    return 117;
+  operator ==(dynamic other) → dynamic
+    return true;
+  method m() → void {}
+}
+class B extends self::A {
+  final field dynamic d = null;
+  synthetic constructor •() → void
+    : super self::A::•()
+    ;
+  get b() → dynamic
+    return null;
+  set c(dynamic x) → dynamic {}
+  set i(dynamic x) → dynamic {}
+}
+class C extends self::B {
+  synthetic constructor •() → void
+    : super self::B::•()
+    ;
+  method test() → dynamic {
+    super.{self::A::~}();
+    self::use(super.{self::A::~}());
+    super.{self::A::unary-}();
+    self::use(super.{self::A::unary-}());
+    super.{self::A::==}(87);
+    self::use(super.{self::A::==}(87));
+    !super.{self::A::==}(87);
+    self::use(!super.{self::A::==}(87));
+    super.{self::A::a};
+    self::use(super.{self::A::a});
+    super.{self::B::b};
+    self::use(super.{self::B::b});
+    super.{self::A::c};
+    self::use(super.{self::A::c});
+    super.{self::B::d};
+    self::use(super.{self::B::d});
+    super.{self::A::e};
+    self::use(super.{self::A::e});
+    super.{self::A::f};
+    self::use(super.{self::A::f});
+    super.g;
+    self::use(super.g);
+    super.{self::A::h};
+    self::use(super.{self::A::h});
+    super.{self::A::i};
+    self::use(super.{self::A::i});
+    super.{self::A::[]}(87);
+    self::use(super.{self::A::[]}(87));
+    super.{self::A::m};
+    self::use(super.{self::A::m});
+    super.{self::A::a} = super.{self::A::a}.+(1);
+    self::use(let final dynamic #t1 = super.{self::A::a} in let final dynamic #t2 = super.{self::A::a} = #t1.+(1) in #t1);
+    super.{self::A::b} = super.{self::B::b}.+(1);
+    self::use(let final dynamic #t3 = super.{self::B::b} in let final dynamic #t4 = super.{self::A::b} = #t3.+(1) in #t3);
+    super.{self::B::c} = super.{self::A::c}.+(1);
+    self::use(let final dynamic #t5 = super.{self::A::c} in let final dynamic #t6 = super.{self::B::c} = #t5.+(1) in #t5);
+    super.{self::A::d} = super.{self::B::d}.+(1);
+    self::use(let final dynamic #t7 = super.{self::B::d} in let final dynamic #t8 = super.{self::A::d} = #t7.+(1) in #t7);
+    super.e = super.{self::A::e}.+(1);
+    self::use(let final dynamic #t9 = super.{self::A::e} in let final dynamic #t10 = super.e = #t9.+(1) in #t9);
+    super.f = super.{self::A::f}.+(1);
+    self::use(let final dynamic #t11 = super.{self::A::f} in let final dynamic #t12 = super.f = #t11.+(1) in #t11);
+    super.{self::A::g} = super.g.+(1);
+    self::use(let final dynamic #t13 = super.g in let final dynamic #t14 = super.{self::A::g} = #t13.+(1) in #t13);
+    super.{self::A::h} = super.{self::A::h}.+(1);
+    self::use(let final dynamic #t15 = super.{self::A::h} in let final dynamic #t16 = super.{self::A::h} = #t15.+(1) in #t15);
+    super.{self::B::i} = super.{self::A::i}.+(1);
+    self::use(let final dynamic #t17 = super.{self::A::i} in let final dynamic #t18 = super.{self::B::i} = #t17.+(1) in #t17);
+    let final dynamic #t19 = 87 in super.{self::A::[]=}(#t19, super.{self::A::[]}(#t19).+(1));
+    self::use(let final dynamic #t20 = 87 in let final dynamic #t21 = super.{self::A::[]}(#t20) in let final dynamic #t22 = super.{self::A::[]=}(#t20, #t21.+(1)) in #t21);
+    super.m = super.{self::A::m}.+(1);
+    self::use(let final dynamic #t23 = super.{self::A::m} in let final dynamic #t24 = super.m = #t23.+(1) in #t23);
+    super.{self::A::a} = super.{self::A::a}.+(1);
+    self::use(super.{self::A::a} = super.{self::A::a}.+(1));
+    super.{self::A::b} = super.{self::B::b}.+(1);
+    self::use(super.{self::A::b} = super.{self::B::b}.+(1));
+    super.{self::B::c} = super.{self::A::c}.+(1);
+    self::use(super.{self::B::c} = super.{self::A::c}.+(1));
+    super.{self::A::d} = super.{self::B::d}.+(1);
+    self::use(super.{self::A::d} = super.{self::B::d}.+(1));
+    super.e = super.{self::A::e}.+(1);
+    self::use(super.e = super.{self::A::e}.+(1));
+    super.f = super.{self::A::f}.+(1);
+    self::use(super.f = super.{self::A::f}.+(1));
+    super.{self::A::g} = super.g.+(1);
+    self::use(super.{self::A::g} = super.g.+(1));
+    super.{self::A::h} = super.{self::A::h}.+(1);
+    self::use(super.{self::A::h} = super.{self::A::h}.+(1));
+    super.{self::B::i} = super.{self::A::i}.+(1);
+    self::use(super.{self::B::i} = super.{self::A::i}.+(1));
+    let final dynamic #t25 = 87 in let final dynamic #t26 = super.{self::A::[]}(#t25).+(1) in let final dynamic #t27 = super.{self::A::[]=}(#t25, #t26) in #t26;
+    self::use(let final dynamic #t28 = 87 in let final dynamic #t29 = super.{self::A::[]}(#t28).+(1) in let final dynamic #t30 = super.{self::A::[]=}(#t28, #t29) in #t29);
+    super.m = super.{self::A::m}.+(1);
+    self::use(super.m = super.{self::A::m}.+(1));
+    super.{self::A::a}.call();
+    self::use(super.{self::A::a}.call());
+    super.{self::B::b}.call();
+    self::use(super.{self::B::b}.call());
+    super.{self::A::c}.call();
+    self::use(super.{self::A::c}.call());
+    super.{self::B::d}.call();
+    self::use(super.{self::B::d}.call());
+    super.{self::A::e}.call();
+    self::use(super.{self::A::e}.call());
+    super.{self::A::f}.call();
+    self::use(super.{self::A::f}.call());
+    super.g();
+    self::use(super.g());
+    super.{self::A::h}.call();
+    self::use(super.{self::A::h}.call());
+    super.{self::A::i}.call();
+    self::use(super.{self::A::i}.call());
+    super.{self::A::[]}(87).call();
+    self::use(super.{self::A::[]}(87).call());
+    super.{self::A::m}();
+    self::use(super.{self::A::m}());
+    super.{self::A::m}(87);
+    self::use(super.{self::A::m}(87));
+    super.{self::A::a} = 42;
+    self::use(super.{self::A::a} = 42);
+    super.{self::A::b} = 42;
+    self::use(super.{self::A::b} = 42);
+    super.{self::B::c} = 42;
+    self::use(super.{self::B::c} = 42);
+    super.{self::A::d} = 42;
+    self::use(super.{self::A::d} = 42);
+    super.e = 42;
+    self::use(super.e = 42);
+    super.f = 42;
+    self::use(super.f = 42);
+    super.{self::A::g} = 42;
+    self::use(super.{self::A::g} = 42);
+    super.{self::A::h} = 42;
+    self::use(super.{self::A::h} = 42);
+    super.{self::B::i} = 42;
+    self::use(super.{self::B::i} = 42);
+    super.{self::A::[]=}(87, 42);
+    self::use(let final dynamic #t31 = 87 in let final dynamic #t32 = 42 in let final dynamic #t33 = super.{self::A::[]=}(#t31, #t32) in #t32);
+    super.m = 42;
+    self::use(super.m = 42);
+    super.{self::A::a}.==(null) ? super.{self::A::a} = 42 : null;
+    self::use(let final dynamic #t34 = super.{self::A::a} in #t34.==(null) ? super.{self::A::a} = 42 : #t34);
+    super.{self::B::b}.==(null) ? super.{self::A::b} = 42 : null;
+    self::use(let final dynamic #t35 = super.{self::B::b} in #t35.==(null) ? super.{self::A::b} = 42 : #t35);
+    super.{self::A::c}.==(null) ? super.{self::B::c} = 42 : null;
+    self::use(let final dynamic #t36 = super.{self::A::c} in #t36.==(null) ? super.{self::B::c} = 42 : #t36);
+    super.{self::B::d}.==(null) ? super.{self::A::d} = 42 : null;
+    self::use(let final dynamic #t37 = super.{self::B::d} in #t37.==(null) ? super.{self::A::d} = 42 : #t37);
+    super.{self::A::e}.==(null) ? super.e = 42 : null;
+    self::use(let final dynamic #t38 = super.{self::A::e} in #t38.==(null) ? super.e = 42 : #t38);
+    super.{self::A::f}.==(null) ? super.f = 42 : null;
+    self::use(let final dynamic #t39 = super.{self::A::f} in #t39.==(null) ? super.f = 42 : #t39);
+    super.g.==(null) ? super.{self::A::g} = 42 : null;
+    self::use(let final dynamic #t40 = super.g in #t40.==(null) ? super.{self::A::g} = 42 : #t40);
+    super.{self::A::h}.==(null) ? super.{self::A::h} = 42 : null;
+    self::use(let final dynamic #t41 = super.{self::A::h} in #t41.==(null) ? super.{self::A::h} = 42 : #t41);
+    super.{self::A::i}.==(null) ? super.{self::B::i} = 42 : null;
+    self::use(let final dynamic #t42 = super.{self::A::i} in #t42.==(null) ? super.{self::B::i} = 42 : #t42);
+    let final dynamic #t43 = 87 in super.{self::A::[]}(#t43).==(null) ? let final dynamic #t44 = 42 in let final dynamic #t45 = super.{self::A::[]=}(#t43, #t44) in #t44 : null;
+    self::use(let final dynamic #t46 = 87 in let final dynamic #t47 = super.{self::A::[]}(#t46) in #t47.==(null) ? let final dynamic #t48 = 42 in let final dynamic #t49 = super.{self::A::[]=}(#t46, #t48) in #t48 : #t47);
+    super.{self::A::m}.==(null) ? super.m = 42 : null;
+    self::use(let final dynamic #t50 = super.{self::A::m} in #t50.==(null) ? super.m = 42 : #t50);
+    super.{self::A::a} = super.{self::A::a}.+(42);
+    self::use(super.{self::A::a} = super.{self::A::a}.+(42));
+    super.{self::A::b} = super.{self::B::b}.+(42);
+    self::use(super.{self::A::b} = super.{self::B::b}.+(42));
+    super.{self::B::c} = super.{self::A::c}.+(42);
+    self::use(super.{self::B::c} = super.{self::A::c}.+(42));
+    super.{self::A::d} = super.{self::B::d}.+(42);
+    self::use(super.{self::A::d} = super.{self::B::d}.+(42));
+    super.e = super.{self::A::e}.+(42);
+    self::use(super.e = super.{self::A::e}.+(42));
+    super.f = super.{self::A::f}.+(42);
+    self::use(super.f = super.{self::A::f}.+(42));
+    super.{self::A::g} = super.g.+(42);
+    self::use(super.{self::A::g} = super.g.+(42));
+    super.{self::A::h} = super.{self::A::h}.+(42);
+    self::use(super.{self::A::h} = super.{self::A::h}.+(42));
+    super.{self::B::i} = super.{self::A::i}.+(42);
+    self::use(super.{self::B::i} = super.{self::A::i}.+(42));
+    let final dynamic #t51 = 87 in super.{self::A::[]=}(#t51, super.{self::A::[]}(#t51).+(42));
+    self::use(let final dynamic #t52 = 87 in let final dynamic #t53 = super.{self::A::[]}(#t52).+(42) in let final dynamic #t54 = super.{self::A::[]=}(#t52, #t53) in #t53);
+    super.m = super.{self::A::m}.+(42);
+    self::use(super.m = super.{self::A::m}.+(42));
+    super.{self::A::a} = super.{self::A::a}.-(42);
+    self::use(super.{self::A::a} = super.{self::A::a}.-(42));
+    super.{self::A::b} = super.{self::B::b}.-(42);
+    self::use(super.{self::A::b} = super.{self::B::b}.-(42));
+    super.{self::B::c} = super.{self::A::c}.-(42);
+    self::use(super.{self::B::c} = super.{self::A::c}.-(42));
+    super.{self::A::d} = super.{self::B::d}.-(42);
+    self::use(super.{self::A::d} = super.{self::B::d}.-(42));
+    super.e = super.{self::A::e}.-(42);
+    self::use(super.e = super.{self::A::e}.-(42));
+    super.f = super.{self::A::f}.-(42);
+    self::use(super.f = super.{self::A::f}.-(42));
+    super.{self::A::g} = super.g.-(42);
+    self::use(super.{self::A::g} = super.g.-(42));
+    super.{self::A::h} = super.{self::A::h}.-(42);
+    self::use(super.{self::A::h} = super.{self::A::h}.-(42));
+    super.{self::B::i} = super.{self::A::i}.-(42);
+    self::use(super.{self::B::i} = super.{self::A::i}.-(42));
+    let final dynamic #t55 = 87 in super.{self::A::[]=}(#t55, super.{self::A::[]}(#t55).-(42));
+    self::use(let final dynamic #t56 = 87 in let final dynamic #t57 = super.{self::A::[]}(#t56).-(42) in let final dynamic #t58 = super.{self::A::[]=}(#t56, #t57) in #t57);
+    super.m = super.{self::A::m}.-(42);
+    self::use(super.m = super.{self::A::m}.-(42));
+  }
+}
+static method use(dynamic x) → dynamic {
+  if(x.==(new core::DateTime::now().millisecondsSinceEpoch))
+    throw "Shouldn't happen";
+}
+static method main() → dynamic {
+  try {
+    new self::C::•().test();
+  }
+  on core::NoSuchMethodError catch(no-exception-var) {
+    return;
+  }
+  throw "Test failed";
+}
diff --git a/pkg/front_end/testcases/top_level_accessors.dart.direct.transformed.expect b/pkg/front_end/testcases/top_level_accessors.dart.direct.transformed.expect
new file mode 100644
index 0000000..35b8eac
--- /dev/null
+++ b/pkg/front_end/testcases/top_level_accessors.dart.direct.transformed.expect
@@ -0,0 +1,13 @@
+library top_level_accessors;
+import self as self;
+import "dart:core" as core;
+
+static set /* from org-dartlang-testcase:///top_level_accessors_part.dart */ exitCode(core::int code) → void {
+  core::print(code);
+}
+static get /* from org-dartlang-testcase:///top_level_accessors_part.dart */ exitCode() → core::int
+  return 0;
+static method /* from org-dartlang-testcase:///top_level_accessors_part.dart */ main() → dynamic {
+  self::exitCode = 42;
+  core::print(self::exitCode);
+}
diff --git a/pkg/front_end/testcases/type_variable_prefix.dart.direct.transformed.expect b/pkg/front_end/testcases/type_variable_prefix.dart.direct.transformed.expect
new file mode 100644
index 0000000..b588a3e
--- /dev/null
+++ b/pkg/front_end/testcases/type_variable_prefix.dart.direct.transformed.expect
@@ -0,0 +1,15 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method method() → invalid-type
+    return "Hello, World!";
+}
+static method main() → dynamic {
+  core::String s = new self::C::•<dynamic>().method();
+  core::print(s);
+}
diff --git a/pkg/front_end/testcases/type_variable_prefix.dart.strong.transformed.expect b/pkg/front_end/testcases/type_variable_prefix.dart.strong.transformed.expect
new file mode 100644
index 0000000..221c1b2
--- /dev/null
+++ b/pkg/front_end/testcases/type_variable_prefix.dart.strong.transformed.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C<T extends core::Object> extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method method() → invalid-type
+    return let final core::String #t1 = "Hello, World!" in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/type_variable_prefix.dart:8:24: Error: A value of type 'dart.core::String' can't be assigned to a variable of type 'invalid-type'.
+Try changing the type of the left hand side, or casting the right hand side to 'invalid-type'.
+  T.String method() => \"Hello, World!\";
+                       ^";
+}
+static const field dynamic #errors = const <dynamic>["pkg/front_end/testcases/type_variable_prefix.dart:8:3: Error: Type 'T.String' not found.
+  T.String method() => \"Hello, World!\";
+  ^"]/* from null */;
+static method main() → dynamic {
+  core::String s = let final invalid-type #t2 = new self::C::•<dynamic>().{self::C::method}() in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/type_variable_prefix.dart:12:24: Error: A value of type 'invalid-type' can't be assigned to a variable of type 'dart.core::String'.
+Try changing the type of the left hand side, or casting the right hand side to 'dart.core::String'.
+  T.String s = new C().method();
+                       ^";
+  core::print(s);
+}
diff --git a/pkg/front_end/testcases/typedef.dart.direct.transformed.expect b/pkg/front_end/testcases/typedef.dart.direct.transformed.expect
new file mode 100644
index 0000000..03c71df
--- /dev/null
+++ b/pkg/front_end/testcases/typedef.dart.direct.transformed.expect
@@ -0,0 +1,12 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef _NullaryFunction = () → dynamic;
+typedef _UnaryFunction = (dynamic) → dynamic;
+typedef _BinaryFunction = (dynamic, dynamic) → dynamic;
+static method main() → dynamic {
+  core::print(self::main is () → dynamic);
+  core::print(self::main is (dynamic) → dynamic);
+  core::print(self::main is (dynamic, dynamic) → dynamic);
+}
diff --git a/pkg/front_end/testcases/undefined.dart.direct.transformed.expect b/pkg/front_end/testcases/undefined.dart.direct.transformed.expect
new file mode 100644
index 0000000..e3bfd98
--- /dev/null
+++ b/pkg/front_end/testcases/undefined.dart.direct.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → void {}
+}
+static method test(self::C c) → void {
+  c.x;
+  c.y;
+  c.f();
+  c.g();
+  c.x = null;
+  c.y = null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/undefined.dart.strong.transformed.expect b/pkg/front_end/testcases/undefined.dart.strong.transformed.expect
new file mode 100644
index 0000000..40d46b1
--- /dev/null
+++ b/pkg/front_end/testcases/undefined.dart.strong.transformed.expect
@@ -0,0 +1,29 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic x = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method f() → void {}
+}
+static method test(self::C c) → void {
+  c.{self::C::x};
+  let final self::C #t1 = c in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/undefined.dart:14:33: Error: The getter 'y' isn't defined for the class '#lib1::C'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'y'.
+  c. /*@error=UndefinedGetter*/ y;
+                                ^";
+  c.{self::C::f}();
+  let final self::C #t2 = c in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/undefined.dart:16:33: Error: The method 'g' isn't defined for the class '#lib1::C'.
+Try correcting the name to the name of an existing method, or defining a method named 'g'.
+  c. /*@error=UndefinedMethod*/ g();
+                                ^";
+  c.{self::C::x} = null;
+  let final self::C #t3 = c in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/undefined.dart:18:33: Error: The setter 'y' isn't defined for the class '#lib1::C'.
+Try correcting the name to the name of an existing setter, or defining a setter or field named 'y'.
+  c. /*@error=UndefinedSetter*/ y = null;
+                                ^";
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.transformed.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.transformed.expect
new file mode 100644
index 0000000..ceea877
--- /dev/null
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.direct.transformed.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(dynamic value) → void;
+}
+static method test(self::C c) → void {
+  c.x = 1;
+  let final dynamic #t1 = c in #t1.x = #t1.x.+(1);
+  let final dynamic #t2 = c in #t2.x.==(null) ? #t2.x = 1 : null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
new file mode 100644
index 0000000..c1dd51a
--- /dev/null
+++ b/pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart.strong.transformed.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract set x(dynamic value) → void;
+}
+static method test(self::C c) → void {
+  c.{self::C::x} = 1;
+  let final self::C #t1 = c in #t1.{self::C::x} = (let final self::C #t2 = #t1 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:13:33: Error: The getter 'x' isn't defined for the class '#lib1::C'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
+  c. /*@error=UndefinedGetter*/ x += 1;
+                                ^").+(1);
+  let final self::C #t3 = c in (let final self::C #t4 = #t3 in let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/undefined_getter_in_compound_assignment.dart:14:33: Error: The getter 'x' isn't defined for the class '#lib1::C'.
+Try correcting the name to the name of an existing getter, or defining a getter or field named 'x'.
+  c. /*@error=UndefinedGetter*/ x ??= 1;
+                                ^").==(null) ?{dynamic} #t3.{self::C::x} = 1 : null;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/unused_methods.dart.direct.transformed.expect b/pkg/front_end/testcases/unused_methods.dart.direct.transformed.expect
new file mode 100644
index 0000000..9b1c543
--- /dev/null
+++ b/pkg/front_end/testcases/unused_methods.dart.direct.transformed.expect
@@ -0,0 +1,86 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class UnusedClass extends core::Object {
+  constructor •() → void
+    : super core::Object::•() {
+    core::print("Unused");
+  }
+}
+abstract class UsedAsBaseClass extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method usedInSubclass() → void {
+    core::print("Unused");
+  }
+  method calledFromB() → void {
+    this.{self::UsedAsBaseClass::calledFromSubclass}();
+  }
+  method calledFromSubclass() → void {
+    core::print("Unused");
+  }
+}
+class UsedAsInterface extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method usedInSubclass() → void {
+    core::print("Unused");
+  }
+}
+class InstantiatedButMethodsUnused extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method usedInSubclass() → void {
+    core::print("Unused");
+  }
+}
+class ClassA extends self::UsedAsBaseClass implements self::UsedAsInterface, self::InstantiatedButMethodsUnused {
+  synthetic constructor •() → void
+    : super self::UsedAsBaseClass::•()
+    ;
+  method usedInSubclass() → void {
+    core::print("A");
+  }
+}
+class ClassB extends self::UsedAsBaseClass implements self::UsedAsInterface, self::InstantiatedButMethodsUnused {
+  synthetic constructor •() → void
+    : super self::UsedAsBaseClass::•()
+    ;
+  method usedInSubclass() → void {
+    core::print("B");
+    this.{self::UsedAsBaseClass::calledFromB}();
+  }
+  method calledFromSubclass() → void {}
+}
+static method baseClassCall(self::UsedAsBaseClass object) → void {
+  object.usedInSubclass();
+}
+static method interfaceCall(self::UsedAsInterface object) → void {
+  object.usedInSubclass();
+}
+static method exactCallA(self::ClassA object) → void {
+  object.usedInSubclass();
+}
+static method exactCallB(self::ClassB object) → void {
+  object.usedInSubclass();
+}
+static method unusedTopLevel() → dynamic {
+  core::print("Unused");
+}
+static method usedTopLevel() → dynamic {}
+static method main() → dynamic {
+  self::usedTopLevel();
+  self::ClassA a = new self::ClassA::•();
+  self::exactCallA(a);
+  self::baseClassCall(a);
+  self::interfaceCall(a);
+  self::ClassB b = new self::ClassB::•();
+  self::exactCallB(b);
+  self::baseClassCall(b);
+  self::interfaceCall(b);
+  new self::InstantiatedButMethodsUnused::•();
+}
diff --git a/pkg/front_end/testcases/warn_unresolved_sends.dart.direct.transformed.expect b/pkg/front_end/testcases/warn_unresolved_sends.dart.direct.transformed.expect
new file mode 100644
index 0000000..5750f13
--- /dev/null
+++ b/pkg/front_end/testcases/warn_unresolved_sends.dart.direct.transformed.expect
@@ -0,0 +1,65 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class C extends core::Object {
+  field dynamic superField = null;
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method superMethod() → dynamic {}
+  get setterOnly() → dynamic
+    return null;
+  set setterOnly(dynamic _) → void {}
+  get getterOnly() → dynamic
+    return null;
+  set getterOnly(dynamic _) → void {}
+}
+class D extends self::C {
+  field dynamic field = null;
+  synthetic constructor •() → void
+    : super self::C::•()
+    ;
+  set setterOnly(dynamic _) → void {}
+  get getterOnly() → dynamic
+    return null;
+  method method() → dynamic {}
+  method test() → void {
+    this.{self::D::field};
+    this.{self::C::superField};
+    this.{self::D::field} = 0;
+    this.{self::C::superField} = 0;
+    this.{self::D::method}();
+    this.{self::C::superMethod}();
+    this.{self::C::setterOnly};
+    this.{self::D::setterOnly} = 0;
+    this.{self::D::getterOnly};
+    this.{self::C::getterOnly} = 0;
+    this.{self::D::field};
+    this.{self::C::superField};
+    this.{self::D::field} = 0;
+    this.{self::C::superField} = 0;
+    this.{self::D::method}();
+    this.{self::C::superMethod}();
+    this.{self::C::setterOnly};
+    this.{self::D::setterOnly} = 0;
+    this.{self::D::getterOnly};
+    this.{self::C::getterOnly} = 0;
+    this.missingField;
+    this.missingField = 0;
+    this.missingMethod();
+    this.missingField;
+    this.missingField = 0;
+    this.missingMethod();
+  }
+}
+class E extends self::D {
+  field dynamic missingField = null;
+  synthetic constructor •() → void
+    : super self::D::•()
+    ;
+  method missingMethod() → void {}
+}
+static method main() → dynamic {
+  new self::E::•().test();
+}
diff --git a/pkg/front_end/tool/_fasta/bulk_compile.dart b/pkg/front_end/tool/_fasta/bulk_compile.dart
index 6a8c52a..7101a1a 100644
--- a/pkg/front_end/tool/_fasta/bulk_compile.dart
+++ b/pkg/front_end/tool/_fasta/bulk_compile.dart
@@ -52,7 +52,7 @@
         (CompilerContext context) async {
       (await context.options.loadSdkSummary(null))?.computeCanonicalNames();
       CompilerResult result = await generateKernelInternal();
-      result?.program?.unbindCanonicalNames();
+      result?.component?.unbindCanonicalNames();
       return null;
     });
   }
diff --git a/pkg/front_end/tool/_fasta/compile_platform.dart b/pkg/front_end/tool/_fasta/compile_platform.dart
index 738a0f1..5629776 100644
--- a/pkg/front_end/tool/_fasta/compile_platform.dart
+++ b/pkg/front_end/tool/_fasta/compile_platform.dart
@@ -18,7 +18,8 @@
 import 'package:front_end/src/fasta/deprecated_problems.dart'
     show deprecated_InputError;
 
-import 'package:front_end/src/fasta/kernel/utils.dart' show writeProgramToFile;
+import 'package:front_end/src/fasta/kernel/utils.dart'
+    show writeComponentToFile;
 
 import 'package:front_end/src/fasta/severity.dart' show Severity;
 
@@ -67,7 +68,7 @@
   }
 
   var result =
-      await generateKernelInternal(buildSummary: true, buildProgram: true);
+      await generateKernelInternal(buildSummary: true, buildComponent: true);
   if (result == null) {
     exitCode = 1;
     // Note: an error should have been reported by now.
@@ -76,10 +77,10 @@
   }
   new File.fromUri(outlineOutput).writeAsBytesSync(result.summary);
   c.options.ticker.logMs("Wrote outline to ${outlineOutput.toFilePath()}");
-  await writeProgramToFile(result.program, fullOutput,
+  await writeComponentToFile(result.component, fullOutput,
       filter: (lib) => !lib.isExternal);
 
-  c.options.ticker.logMs("Wrote program to ${fullOutput.toFilePath()}");
+  c.options.ticker.logMs("Wrote component to ${fullOutput.toFilePath()}");
 
   List<Uri> deps = result.deps.toList();
   deps.addAll(await getDependencies(Platform.script,
diff --git a/pkg/front_end/tool/_fasta/dump_partial.dart b/pkg/front_end/tool/_fasta/dump_partial.dart
index b97ba45..610fdb7 100644
--- a/pkg/front_end/tool/_fasta/dump_partial.dart
+++ b/pkg/front_end/tool/_fasta/dump_partial.dart
@@ -16,18 +16,18 @@
     return;
   }
 
-  var program = _loadProgram(args);
-  writeProgramToText(program);
+  var component = _loadComponent(args);
+  writeComponentToText(component);
 }
 
-/// Creates a program that contains all of the context code marked as external,
+/// Creates a component that contains all of the context code marked as external,
 /// and all libraries defined in partial.dill as they are written in that file.
-Program _loadProgram(List<String> args) {
+Component _loadComponent(List<String> args) {
   List<int> partialInput = new File(args[0]).readAsBytesSync();
 
-  var context = new Program();
+  var context = new Component();
   for (var i = 1; i < args.length; i++) {
-    loadProgramFromBinary(args[i], context);
+    loadComponentFromBinary(args[i], context);
   }
 
   Set<Uri> libraries = _definedLibraries(partialInput, context);
@@ -36,30 +36,30 @@
   // of libraries that are mentioned in more than one .dill file. In order to
   // keep the contents of partial.dill intact, we build a new context that
   // excludes those libraries defined in partial.dill.
-  List<int> contextBytes = serializeProgram(context,
+  List<int> contextBytes = serializeComponent(context,
       filter: (l) => !libraries.contains(l.importUri));
-  var program = new Program();
-  loadProgramFromBytes(contextBytes, program);
-  _updateIsExternal(program, true);
-  loadProgramFromBytes(partialInput, program);
-  return program;
+  var component = new Component();
+  loadComponentFromBytes(contextBytes, component);
+  _updateIsExternal(component, true);
+  loadComponentFromBytes(partialInput, component);
+  return component;
 }
 
 /// Compute the set of libraries defined in [partialDill].
 ///
-/// The [context] program contains all other libraries that may be needed to
+/// The [context] component contains all other libraries that may be needed to
 /// properly deserialize partialDill.
 ///
 /// Note: This function will mutate [context] in place.
 // TODO(sigmund): simplify and get rid of [context]. We could do that with a
 // custom deserialization, but it will be easier to do once .dill has
 // random-access support.
-Set<Uri> _definedLibraries(List<int> partialDill, Program context) {
+Set<Uri> _definedLibraries(List<int> partialDill, Component context) {
   _updateIsExternal(context, true);
 
   // This implicitly sets `isExternal = false` on all libraries defined in the
   // partial.dill file.
-  loadProgramFromBytes(partialDill, context);
+  loadComponentFromBytes(partialDill, context);
   var result = context.libraries
       .where((l) => !l.isExternal)
       .map((l) => l.importUri)
@@ -68,6 +68,6 @@
   return result;
 }
 
-void _updateIsExternal(Program program, bool toValue) {
-  program.libraries.forEach((lib) => lib.isExternal = toValue);
+void _updateIsExternal(Component component, bool toValue) {
+  component.libraries.forEach((lib) => lib.isExternal = toValue);
 }
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index 8411f0e..78d1163 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -13,7 +13,7 @@
 import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
 
 import 'package:kernel/kernel.dart'
-    show CanonicalName, Library, Program, Source, loadProgramFromBytes;
+    show CanonicalName, Library, Component, Source, loadComponentFromBytes;
 
 import 'package:kernel/target/targets.dart' show TargetFlags, targets;
 
@@ -34,7 +34,7 @@
     show KernelTarget;
 
 import 'package:front_end/src/fasta/kernel/utils.dart'
-    show printProgramText, writeProgramToFile;
+    show printComponentText, writeComponentToFile;
 
 import 'package:front_end/src/fasta/severity.dart' show Severity;
 
@@ -91,7 +91,7 @@
 
   Uri platformUri;
 
-  Program platformComponent;
+  Component platformComponent;
 
   BatchCompiler(this.lines);
 
@@ -233,10 +233,10 @@
     await dillTarget.buildOutlines();
     var outline = await kernelTarget.buildOutlines();
     if (c.options.debugDump && output != null) {
-      printProgramText(outline, libraryFilter: kernelTarget.isSourceLibrary);
+      printComponentText(outline, libraryFilter: kernelTarget.isSourceLibrary);
     }
     if (output != null) {
-      await writeProgramToFile(outline, output);
+      await writeComponentToFile(outline, output);
       ticker.logMs("Wrote outline to ${output.toFilePath()}");
     }
     return kernelTarget;
@@ -245,35 +245,37 @@
   Future<Uri> compile({bool sansPlatform: false}) async {
     KernelTarget kernelTarget = await buildOutline();
     Uri uri = c.options.output;
-    Program program = await kernelTarget.buildProgram(verify: c.options.verify);
+    Component component =
+        await kernelTarget.buildComponent(verify: c.options.verify);
     if (c.options.debugDump) {
-      printProgramText(program, libraryFilter: kernelTarget.isSourceLibrary);
+      printComponentText(component,
+          libraryFilter: kernelTarget.isSourceLibrary);
     }
     if (sansPlatform) {
-      program.computeCanonicalNames();
-      Program userCode = new Program(
-          nameRoot: program.root,
-          uriToSource: new Map<Uri, Source>.from(program.uriToSource));
-      userCode.mainMethodName = program.mainMethodName;
-      for (Library library in program.libraries) {
+      component.computeCanonicalNames();
+      Component userCode = new Component(
+          nameRoot: component.root,
+          uriToSource: new Map<Uri, Source>.from(component.uriToSource));
+      userCode.mainMethodName = component.mainMethodName;
+      for (Library library in component.libraries) {
         if (library.importUri.scheme != "dart") {
           userCode.libraries.add(library);
         }
       }
-      program = userCode;
+      component = userCode;
     }
     if (uri.scheme == "file") {
-      await writeProgramToFile(program, uri);
-      ticker.logMs("Wrote program to ${uri.toFilePath()}");
+      await writeComponentToFile(component, uri);
+      ticker.logMs("Wrote component to ${uri.toFilePath()}");
     }
     return uri;
   }
 }
 
-/// Load the [Program] from the given [uri] and append its libraries
+/// Load the [Component] from the given [uri] and append its libraries
 /// to the [dillTarget].
 void _appendDillForUri(DillTarget dillTarget, Uri uri) {
   var bytes = new File.fromUri(uri).readAsBytesSync();
-  var platformProgram = loadProgramFromBytes(bytes);
+  var platformProgram = loadComponentFromBytes(bytes);
   dillTarget.loader.appendLibraries(platformProgram, byteCount: bytes.length);
 }
diff --git a/pkg/front_end/tool/example.dart b/pkg/front_end/tool/example.dart
index a826fe8..56966d1 100644
--- a/pkg/front_end/tool/example.dart
+++ b/pkg/front_end/tool/example.dart
@@ -7,22 +7,22 @@
 import 'package:front_end/src/api_prototype/kernel_generator.dart';
 import 'package:front_end/src/api_prototype/compiler_options.dart';
 import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/kernel.dart' show Program;
+import 'package:kernel/kernel.dart' show Component;
 
-Future dumpToSink(Program program, StreamSink<List<int>> sink) {
-  new BinaryPrinter(sink).writeProgramFile(program);
+Future dumpToSink(Component component, StreamSink<List<int>> sink) {
+  new BinaryPrinter(sink).writeComponentFile(component);
   return sink.close();
 }
 
 Future kernelToSink(Uri entry, StreamSink<List<int>> sink) async {
-  var program = await kernelForProgram(
+  var component = await kernelForProgram(
       entry,
       new CompilerOptions()
         ..sdkRoot = new Uri.file('sdk')
         ..packagesFileUri = new Uri.file('.packages')
         ..onError = (e) => print(e.message));
 
-  await dumpToSink(program, sink);
+  await dumpToSink(component, sink);
 }
 
 main(args) async {
diff --git a/pkg/front_end/tool/fasta_perf.dart b/pkg/front_end/tool/fasta_perf.dart
index eb0b2b5..de09e9a 100644
--- a/pkg/front_end/tool/fasta_perf.dart
+++ b/pkg/front_end/tool/fasta_perf.dart
@@ -259,7 +259,7 @@
     Uri.parse('dart:mirrors'),
     Uri.parse('dart:typed_data'),
   ];
-  var program = await kernelForBuildUnit(entrypoints, options);
+  var program = await kernelForComponent(entrypoints, options);
 
   timer.stop();
   var name = 'kernel_gen_e2e${compileSdk ? "" : "_sum"}';
diff --git a/pkg/kernel/bin/count_breakdown.dart b/pkg/kernel/bin/count_breakdown.dart
index 7517816..b3dbc17 100755
--- a/pkg/kernel/bin/count_breakdown.dart
+++ b/pkg/kernel/bin/count_breakdown.dart
@@ -19,9 +19,9 @@
 
 main(List<String> args) {
   CommandLineHelper.requireExactlyOneArgument(true, args, usage);
-  Program program = CommandLineHelper.tryLoadDill(args[0], usage);
+  Component component = CommandLineHelper.tryLoadDill(args[0], usage);
   TypeCounter counter = new TypeCounter();
-  program.accept(counter);
+  component.accept(counter);
   counter.printStats();
 }
 
diff --git a/pkg/kernel/bin/dump.dart b/pkg/kernel/bin/dump.dart
index 32a9058..fc69f95 100755
--- a/pkg/kernel/bin/dump.dart
+++ b/pkg/kernel/bin/dump.dart
@@ -27,7 +27,7 @@
   CommandLineHelper.requireVariableArgumentCount([1, 2], args, usage);
   CommandLineHelper.requireFileExists(args[0], usage);
   var binary = CommandLineHelper.tryLoadDill(args[0], usage);
-  writeProgramToText(binary,
+  writeComponentToText(binary,
       path: args.length > 1 ? args[1] : null,
       showOffsets: const bool.fromEnvironment("showOffsets"));
 }
diff --git a/pkg/kernel/bin/eval.dart b/pkg/kernel/bin/eval.dart
index bdd3dda..491f726 100755
--- a/pkg/kernel/bin/eval.dart
+++ b/pkg/kernel/bin/eval.dart
@@ -21,6 +21,6 @@
 
 main(List<String> args) {
   CommandLineHelper.requireExactlyOneArgument(true, args, usage);
-  Program program = CommandLineHelper.tryLoadDill(args[0], usage);
-  new Interpreter(program).run();
+  Component component = CommandLineHelper.tryLoadDill(args[0], usage);
+  new Interpreter(component).run();
 }
diff --git a/pkg/kernel/bin/size_breakdown.dart b/pkg/kernel/bin/size_breakdown.dart
index 90634e8..c2608ed 100755
--- a/pkg/kernel/bin/size_breakdown.dart
+++ b/pkg/kernel/bin/size_breakdown.dart
@@ -24,8 +24,8 @@
   CommandLineHelper.requireExactlyOneArgument(true, args, usage);
   List<int> bytes = new File(args[0]).readAsBytesSync();
   try {
-    Program p = new Program();
-    new WrappedBinaryBuilder(bytes).readProgram(p);
+    Component p = new Component();
+    new WrappedBinaryBuilder(bytes).readComponent(p);
   } catch (e) {
     print("Argument given isn't a dill file that can be loaded.");
     usage();
@@ -64,9 +64,9 @@
     print("Constant table: ${_bytesToReadable(size)}.");
   }
 
-  Library readLibrary(Program program, int endOffset) {
+  Library readLibrary(Component component, int endOffset) {
     int size = -byteOffset;
-    var result = super.readLibrary(program, endOffset);
+    var result = super.readLibrary(component, endOffset);
     size += super.byteOffset;
     print("Library '${result.importUri}': ${_bytesToReadable(size)}.");
     return result;
diff --git a/pkg/kernel/bin/split.dart b/pkg/kernel/bin/split.dart
index f6de5e4..8a4df58 100755
--- a/pkg/kernel/bin/split.dart
+++ b/pkg/kernel/bin/split.dart
@@ -25,7 +25,7 @@
 
 main(args) async {
   CommandLineHelper.requireExactlyOneArgument(true, args, usage);
-  Program binary = CommandLineHelper.tryLoadDill(args[0], usage);
+  Component binary = CommandLineHelper.tryLoadDill(args[0], usage);
 
   int part = 1;
   binary.libraries.forEach((lib) => lib.isExternal = true);
@@ -36,19 +36,19 @@
         lib.name == "nativewrappers") continue;
     lib.isExternal = false;
     String path = args[0] + ".part${part++}.dill";
-    await writeProgramToFile(binary, path);
+    await writeComponentToFile(binary, path);
     print("Wrote $path");
     lib.isExternal = true;
   }
 }
 
-Future<Null> writeProgramToFile(Program program, String path) async {
+Future<Null> writeComponentToFile(Component component, String path) async {
   File output = new File(path);
   IOSink sink = output.openWrite();
   try {
     BinaryPrinter printer =
         new LimitedBinaryPrinter(sink, (lib) => !lib.isExternal, false);
-    printer.writeProgramFile(program);
+    printer.writeComponentFile(component);
   } finally {
     await sink.close();
   }
diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart
index aabac5e..1898ede 100755
--- a/pkg/kernel/bin/transform.dart
+++ b/pkg/kernel/bin/transform.dart
@@ -37,8 +37,7 @@
       negatable: false,
       help: 'Be verbose (e.g. prints transformed main library).',
       defaultsTo: false)
-  ..addOption('embedder-entry-points-manifest',
-      allowMultiple: true,
+  ..addMultiOption('embedder-entry-points-manifest',
       help: 'A path to a file describing entrypoints '
           '(lines of the form `<library>,<class>,<member>`).')
   ..addOption('transformation',
@@ -83,23 +82,23 @@
   List<treeshaker.ProgramRoot> programRoots =
       parseProgramRoots(embedderEntryPointManifests);
 
-  var program = loadProgramFromBinary(input);
+  var component = loadComponentFromBinary(input);
 
-  final coreTypes = new CoreTypes(program);
-  final hierarchy = new ClassHierarchy(program);
+  final coreTypes = new CoreTypes(component);
+  final hierarchy = new ClassHierarchy(component);
   switch (options['transformation']) {
     case 'continuation':
-      program = cont.transformProgram(coreTypes, program, syncAsync);
+      component = cont.transformComponent(coreTypes, component, syncAsync);
       break;
     case 'resolve-mixins':
       mix.transformLibraries(
-          new NoneTarget(null), coreTypes, hierarchy, program.libraries);
+          new NoneTarget(null), coreTypes, hierarchy, component.libraries);
       break;
     case 'closures':
-      program = closures.transformProgram(coreTypes, program);
+      component = closures.transformComponent(coreTypes, component);
       break;
     case 'coq':
-      program = coq.transformProgram(coreTypes, program);
+      component = coq.transformComponent(coreTypes, component);
       break;
     case 'constants':
       // We use the -D defines supplied to this VM instead of explicitly using a
@@ -107,17 +106,18 @@
       final Map<String, String> defines = null;
       final VmConstantsBackend backend =
           new VmConstantsBackend(defines, coreTypes);
-      program = constants.transformProgram(program, backend);
+      component = constants.transformComponent(component, backend);
       break;
     case 'treeshake':
-      program = treeshaker.transformProgram(coreTypes, hierarchy, program,
+      component = treeshaker.transformComponent(coreTypes, hierarchy, component,
           programRoots: programRoots);
       break;
     case 'methodcall':
-      program = method_call.transformProgram(coreTypes, hierarchy, program);
+      component =
+          method_call.transformComponent(coreTypes, hierarchy, component);
       break;
     case 'empty':
-      program = empty.transformProgram(program);
+      component = empty.transformComponent(component);
       break;
     default:
       throw 'Unknown transformation';
@@ -126,17 +126,17 @@
   // TODO(30631): Fix the verifier so we can check that the transform produced
   // valid output.
   //
-  // verifyProgram(program);
+  // verifyComponent(component);
 
   if (format == 'text') {
-    writeProgramToText(program, path: output);
+    writeComponentToText(component, path: output);
   } else {
     assert(format == 'bin');
-    await writeProgramToBinary(program, output);
+    await writeComponentToBinary(component, output);
   }
 
   if (verbose) {
-    writeLibraryToText(program.mainMethod.parent as Library);
+    writeLibraryToText(component.mainMethod.parent as Library);
   }
 
   return CompilerOutcome.Ok;
diff --git a/pkg/kernel/bin/type_check.dart b/pkg/kernel/bin/type_check.dart
index 2c062de..e732ab6 100755
--- a/pkg/kernel/bin/type_check.dart
+++ b/pkg/kernel/bin/type_check.dart
@@ -24,7 +24,7 @@
   CommandLineHelper.requireExactlyOneArgument(true, args, usage);
   final binary = CommandLineHelper.tryLoadDill(args[0], usage);
   ErrorFormatter errorFormatter = new ErrorFormatter();
-  new StrongModeTypeChecker(errorFormatter, binary)..checkProgram(binary);
+  new StrongModeTypeChecker(errorFormatter, binary)..checkComponent(binary);
   if (errorFormatter.numberOfFailures > 0) {
     errorFormatter.failures.forEach(print);
     print('------- Found ${errorFormatter.numberOfFailures} errors -------');
diff --git a/pkg/kernel/bin/util.dart b/pkg/kernel/bin/util.dart
index 315869b..35988b5 100644
--- a/pkg/kernel/bin/util.dart
+++ b/pkg/kernel/bin/util.dart
@@ -93,9 +93,9 @@
     }
   }
 
-  static Program tryLoadDill(String file, void Function() usage) {
+  static Component tryLoadDill(String file, void Function() usage) {
     try {
-      return loadProgramFromBinary(file);
+      return loadComponentFromBinary(file);
     } catch (e) {
       print("Argument '$file' isn't a dill file that can be loaded.");
       usage();
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index a8ae768e..9305d16 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -75,11 +75,11 @@
 }
 
 type StringReference {
-  UInt index; // Index into the Program's strings.
+  UInt index; // Index into the Component's strings.
 }
 
 type ConstantReference {
-  UInt index; // Index into the Program's constants.
+  UInt index; // Index into the Component's constants.
 }
 
 type SourceInfo {
@@ -127,7 +127,7 @@
   StringReference name;
 }
 
-type ProgramFile {
+type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
   UInt32 formatVersion;
   MetadataPayload[] metadataPayloads;
@@ -137,7 +137,7 @@
   RList<MetadataMapping> metadataMappings;
   StringTable strings;
   List<Constant> constants;
-  ProgramIndex programIndex;
+  ComponentIndex componentIndex;
 }
 
 // Backend specific metadata section.
@@ -152,12 +152,12 @@
                               // they are encoded as indices in this array.
 }
 
-// Program index with all fixed-size-32-bit integers.
+// Component index with all fixed-size-32-bit integers.
 // This gives "semi-random-access" to certain parts of the binary.
 // By reading the last 4 bytes one knows the number of libaries,
-// which allows to skip to any other field in this program index,
+// which allows to skip to any other field in this component index,
 // which again allows to skip to what it points to.
-type ProgramIndex {
+type ComponentIndex {
   UInt32 binaryOffsetForSourceTable;
   UInt32 binaryOffsetForCanonicalNames;
   UInt32 binaryOffsetForStringTable;
@@ -165,7 +165,7 @@
   UInt32 mainMethodReference; // This is a ProcedureReference with a fixed-size integer.
   UInt32[libraryCount + 1] libraryOffsets;
   UInt32 libraryCount;
-  UInt32 programFileSizeInBytes;
+  UInt32 componentFileSizeInBytes;
 }
 
 type LibraryReference {
@@ -238,15 +238,15 @@
 }
 
 type LibraryPart {
-  List<Expression> annotations;
   UriReference fileUri;
+  List<Expression> annotations;
 }
 
 type Typedef {
   CanonicalNameReference canonicalName;
+  UriReference fileUri;
   FileOffset fileOffset;
   StringReference name;
-  UriReference fileUri;
   List<Expression> annotations;
   List<TypeParameter> typeParameters;
   DartType type;
@@ -279,12 +279,12 @@
 type Class extends Node {
   Byte tag = 2;
   CanonicalNameReference canonicalName;
+  // An absolute path URI to the .dart file from which the class was created.
+  UriReference fileUri;
   FileOffset fileOffset;
   FileOffset fileEndOffset;
   Byte flags (isAbstract, isEnum, xx); // Where xx is index into ClassLevel
   StringReference name;
-  // An absolute path URI to the .dart file from which the class was created.
-  UriReference fileUri;
   List<Expression> annotations;
   List<TypeParameter> typeParameters;
   Option<DartType> superClass;
@@ -306,14 +306,14 @@
 type Field extends Member {
   Byte tag = 4;
   CanonicalNameReference canonicalName;
+  // An absolute path URI to the .dart file from which the field was created.
+  UriReference fileUri;
   FileOffset fileOffset;
   FileOffset fileEndOffset;
   Byte flags (isFinal, isConst, isStatic, hasImplicitGetter, hasImplicitSetter,
               isCovariant, isGenericCovariantImpl, isGenericCovariantInterface);
   Byte flags2 (isGenericContravariant);
   Name name;
-  // An absolute path URI to the .dart file from which the field was created.
-  UriReference fileUri;
   List<Expression> annotations;
   DartType type;
   Option<Expression> initializer;
@@ -322,11 +322,11 @@
 type Constructor extends Member {
   Byte tag = 5;
   CanonicalNameReference canonicalName;
+  UriReference fileUri;
   FileOffset fileOffset;
   FileOffset fileEndOffset;
   Byte flags (isConst, isExternal, isSynthetic);
   Name name;
-  UriReference fileUri;
   List<Expression> annotations;
   FunctionNode function;
   List<Initializer> initializers;
@@ -345,6 +345,8 @@
 type Procedure extends Member {
   Byte tag = 6;
   CanonicalNameReference canonicalName;
+  // An absolute path URI to the .dart file from which the class was created.
+  UriReference fileUri;
   FileOffset fileOffset;
   FileOffset fileEndOffset;
   Byte kind; // Index into the ProcedureKind enum above.
@@ -352,8 +354,6 @@
               isGenericContravariant, isForwardingSemiStub,
               isRedirectingFactoryConstructor);
   Name name;
-  // An absolute path URI to the .dart file from which the class was created.
-  UriReference fileUri;
   List<Expression> annotations;
   // Only present if the 'isForwardingStub' flag is set.
   Option<MemberReference> forwardingStubSuperTarget;
@@ -365,11 +365,11 @@
 type RedirectingFactoryConstructor extends Member {
   Byte tag = 107;
   CanonicalNameReference canonicalName;
+  UriReference fileUri;
   FileOffset fileOffset;
   FileOffset fileEndOffset;
   Byte flags;
   Name name;
-  UriReference fileUri;
   List<Expression> annotations;
   MemberReference targetReference;
   List<DartType> typeArguments;
@@ -924,6 +924,11 @@
   List<Statement> statements;
 }
 
+type AssertBlock extends Statement {
+  Byte tag = 81;
+  List<Statement> statements;
+}
+
 type EmptyStatement extends Statement {
   Byte tag = 63;
 }
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index ab5b52f..2152cd9 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -64,7 +64,7 @@
 ///
 library kernel.ast;
 
-import 'dart:convert' show UTF8;
+import 'dart:convert' show utf8;
 
 import 'visitor.dart';
 export 'visitor.dart';
@@ -153,7 +153,7 @@
     parent = null;
   }
 
-  Program get enclosingProgram => parent?.enclosingProgram;
+  Component get enclosingComponent => parent?.enclosingComponent;
 
   /// Returns the best known source location of the given AST node, or `null` if
   /// the node is orphaned.
@@ -436,7 +436,7 @@
   String toString() => debugLibraryName(this);
 
   Location _getLocationInEnclosingFile(int offset) {
-    return _getLocationInProgram(enclosingProgram, fileUri, offset);
+    return _getLocationInComponent(enclosingComponent, fileUri, offset);
   }
 }
 
@@ -929,7 +929,7 @@
   }
 
   Location _getLocationInEnclosingFile(int offset) {
-    return _getLocationInProgram(enclosingProgram, fileUri, offset);
+    return _getLocationInComponent(enclosingComponent, fileUri, offset);
   }
 }
 
@@ -1210,7 +1210,7 @@
   DartType get setterType => isMutable ? type : const BottomType();
 
   Location _getLocationInEnclosingFile(int offset) {
-    return _getLocationInProgram(enclosingProgram, fileUri, offset);
+    return _getLocationInComponent(enclosingComponent, fileUri, offset);
   }
 }
 
@@ -1298,7 +1298,7 @@
   DartType get setterType => const BottomType();
 
   Location _getLocationInEnclosingFile(int offset) {
-    return _getLocationInProgram(enclosingProgram, fileUri, offset);
+    return _getLocationInComponent(enclosingComponent, fileUri, offset);
   }
 }
 
@@ -1428,7 +1428,7 @@
   DartType get setterType => const BottomType();
 
   Location _getLocationInEnclosingFile(int offset) {
-    return _getLocationInProgram(enclosingProgram, fileUri, offset);
+    return _getLocationInComponent(enclosingComponent, fileUri, offset);
   }
 }
 
@@ -1671,7 +1671,7 @@
   }
 
   Location _getLocationInEnclosingFile(int offset) {
-    return _getLocationInProgram(enclosingProgram, fileUri, offset);
+    return _getLocationInComponent(enclosingComponent, fileUri, offset);
   }
 }
 
@@ -3814,9 +3814,12 @@
   final List<Statement> statements;
 
   Block(this.statements) {
+    // Ensure statements is mutable.
+    assert((statements
+          ..add(null)
+          ..removeLast()) !=
+        null);
     setParents(statements, this);
-    statements.add(null);
-    statements.removeLast();
   }
 
   accept(StatementVisitor v) => v.visitBlock(this);
@@ -3836,6 +3839,40 @@
   }
 }
 
+/// A block that is only executed when asserts are enabled.
+///
+/// Sometimes arbitrary statements must be guarded by whether asserts are
+/// enabled.  For example, when a subexpression of an assert in async code is
+/// linearized and named, it can produce such a block of statements.
+class AssertBlock extends Statement {
+  final List<Statement> statements;
+
+  AssertBlock(this.statements) {
+    // Ensure statements is mutable.
+    assert((statements
+          ..add(null)
+          ..removeLast()) !=
+        null);
+    setParents(statements, this);
+  }
+
+  accept(StatementVisitor v) => v.visitAssertBlock(this);
+  accept1(StatementVisitor1 v, arg) => v.visitAssertBlock(this, arg);
+
+  transformChildren(Transformer v) {
+    transformList(statements, v, this);
+  }
+
+  visitChildren(Visitor v) {
+    visitList(statements, v);
+  }
+
+  void addStatement(Statement node) {
+    statements.add(node);
+    node.parent = this;
+  }
+}
+
 class EmptyStatement extends Statement {
   accept(StatementVisitor v) => v.visitEmptyStatement(this);
   accept1(StatementVisitor1 v, arg) => v.visitEmptyStatement(this, arg);
@@ -4886,7 +4923,7 @@
 ///
 /// * Access to Vectors is untyped.
 ///
-/// * Vectors can be used by various transformations of Kernel programs.
+/// * Vectors can be used by various transformations of Kernel components.
 /// Currently they are used by Closure Conversion to represent closure contexts.
 class VectorType extends DartType {
   const VectorType();
@@ -5546,11 +5583,11 @@
 }
 
 // ------------------------------------------------------------------------
-//                                PROGRAM
+//                                COMPONENT
 // ------------------------------------------------------------------------
 
-/// A way to bundle up all the libraries in a program.
-class Program extends TreeNode {
+/// A way to bundle up libraries in a component.
+class Component extends TreeNode {
   final CanonicalName root;
 
   final List<Library> libraries;
@@ -5568,7 +5605,7 @@
   /// Reference to the main method in one of the libraries.
   Reference mainMethodName;
 
-  Program(
+  Component(
       {CanonicalName nameRoot,
       List<Library> libraries,
       Map<Uri, Source> uriToSource})
@@ -5577,7 +5614,7 @@
         uriToSource = uriToSource ?? <Uri, Source>{} {
     if (libraries != null) {
       for (int i = 0; i < libraries.length; ++i) {
-        // The libraries are owned by this program, and so are their canonical
+        // The libraries are owned by this component, and so are their canonical
         // names if they exist.
         Library library = libraries[i];
         library.parent = this;
@@ -5606,7 +5643,7 @@
     mainMethodName = getMemberReference(main);
   }
 
-  accept(TreeVisitor v) => v.visitProgram(this);
+  accept(TreeVisitor v) => v.visitComponent(this);
 
   visitChildren(Visitor v) {
     visitList(libraries, v);
@@ -5617,7 +5654,7 @@
     transformList(libraries, v, this);
   }
 
-  Program get enclosingProgram => this;
+  Component get enclosingComponent => this;
 
   /// Translates an offset to line and column numbers in the given file.
   Location getLocation(Uri file, int offset) {
@@ -5805,7 +5842,7 @@
     RangeError.checkValueInInterval(line, 1, lineStarts.length, 'line');
     if (source == null) return null;
 
-    cachedText ??= UTF8.decode(source, allowMalformed: true);
+    cachedText ??= utf8.decode(source, allowMalformed: true);
     // -1 as line numbers start at 1.
     int index = line - 1;
     if (index + 1 == lineStarts.length) {
@@ -5940,9 +5977,9 @@
 /// static analysis and runtime behavior of the library are unaffected.
 const informative = null;
 
-Location _getLocationInProgram(Program program, Uri fileUri, int offset) {
-  if (program != null) {
-    return program.getLocation(fileUri, offset);
+Location _getLocationInComponent(Component component, Uri fileUri, int offset) {
+  if (component != null) {
+    return component.getLocation(fileUri, offset);
   } else {
     return new Location(fileUri, TreeNode.noOffset, TreeNode.noOffset);
   }
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index b0aa91d..ce35260 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -22,7 +22,7 @@
   String toString() => '$filename:$byteIndex: $message at $path';
 }
 
-class _ProgramIndex {
+class _ComponentIndex {
   int binaryOffsetForSourceTable;
   int binaryOffsetForStringTable;
   int binaryOffsetForCanonicalNames;
@@ -30,7 +30,7 @@
   int mainMethodReference;
   List<int> libraryOffsets;
   int libraryCount;
-  int programFileSizeInBytes;
+  int componentFileSizeInBytes;
 }
 
 class BinaryBuilder {
@@ -48,7 +48,7 @@
   List<CanonicalName> _linkTable;
   int _transformerFlags = 0;
   Library _currentLibrary;
-  int _programStartOffset = 0;
+  int _componentStartOffset = 0;
 
   // If something goes wrong, this list should indicate what library,
   // class, and member was being built.
@@ -128,15 +128,15 @@
   /// Read metadataMappings section from the binary. Return [true] if
   /// any metadata mapping contains metadata with node references.
   /// In this case we need to disable lazy loading of the binary.
-  bool _readMetadataSection(Program program) {
+  bool _readMetadataSection(Component component) {
     // Default reader ignores metadata section entirely.
     return false;
   }
 
-  /// Process any pending metadata associations. Called once the Program
+  /// Process any pending metadata associations. Called once the Component
   /// is fully deserialized and metadata containing references to nodes can
   /// be safely parsed.
-  void _processPendingMetadataAssociations(Program program) {
+  void _processPendingMetadataAssociations(Component component) {
     // Default reader ignores metadata section entirely.
   }
 
@@ -342,14 +342,14 @@
     }
   }
 
-  List<int> _indexPrograms() {
+  List<int> _indexComponents() {
     int savedByteOffset = _byteOffset;
     _byteOffset = _bytes.length - 4;
     List<int> index = <int>[];
     while (_byteOffset > 0) {
       int size = readUint32();
       int start = _byteOffset - size;
-      if (start < 0) throw "Invalid program file: Indicated size is invalid.";
+      if (start < 0) throw "Invalid component file: Indicated size is invalid.";
       index.add(size);
       _byteOffset = start - 4;
     }
@@ -357,65 +357,65 @@
     return new List.from(index.reversed);
   }
 
-  /// Deserializes a kernel program and stores it in [program].
+  /// Deserializes a kernel component and stores it in [component].
   ///
-  /// When linking with a non-empty program, canonical names must have been
+  /// When linking with a non-empty component, canonical names must have been
   /// computed ahead of time.
   ///
   /// The input bytes may contain multiple files concatenated.
-  void readProgram(Program program) {
-    List<int> programFileSizes = _indexPrograms();
-    if (programFileSizes.length > 1) {
+  void readComponent(Component component) {
+    List<int> componentFileSizes = _indexComponents();
+    if (componentFileSizes.length > 1) {
       _disableLazyReading = true;
     }
-    int programFileIndex = 0;
+    int componentFileIndex = 0;
     while (_byteOffset < _bytes.length) {
-      _readOneProgram(program, programFileSizes[programFileIndex]);
-      ++programFileIndex;
+      _readOneComponent(component, componentFileSizes[componentFileIndex]);
+      ++componentFileIndex;
     }
   }
 
-  /// Reads a single program file from the input and loads it into [program],
-  /// overwriting and reusing any existing data in the program.
+  /// Reads a single component file from the input and loads it into [component],
+  /// overwriting and reusing any existing data in the component.
   ///
-  /// When linking with a non-empty program, canonical names must have been
+  /// When linking with a non-empty component, canonical names must have been
   /// computed ahead of time.
   ///
   /// This should *only* be used when there is a reason to not allow
   /// concatenated files.
-  void readSingleFileProgram(Program program) {
-    List<int> programFileSizes = _indexPrograms();
-    if (programFileSizes.isEmpty) throw "Invalid program data.";
-    _readOneProgram(program, programFileSizes[0]);
+  void readSingleFileComponent(Component component) {
+    List<int> componentFileSizes = _indexComponents();
+    if (componentFileSizes.isEmpty) throw "Invalid component data.";
+    _readOneComponent(component, componentFileSizes[0]);
     if (_byteOffset < _bytes.length) {
       if (_byteOffset + 3 < _bytes.length) {
         int magic = readUint32();
-        if (magic == Tag.ProgramFile) {
-          throw 'Concatenated program file given when a single program '
+        if (magic == Tag.ComponentFile) {
+          throw 'Concatenated component file given when a single component '
               'was expected.';
         }
       }
-      throw 'Unrecognized bytes following program data';
+      throw 'Unrecognized bytes following component data';
     }
   }
 
-  _ProgramIndex _readProgramIndex(int programFileSize) {
+  _ComponentIndex _readComponentIndex(int componentFileSize) {
     int savedByteIndex = _byteOffset;
 
-    _ProgramIndex result = new _ProgramIndex();
+    _ComponentIndex result = new _ComponentIndex();
 
     // There are two fields: file size and library count.
-    _byteOffset = _programStartOffset + programFileSize - (2) * 4;
+    _byteOffset = _componentStartOffset + componentFileSize - (2) * 4;
     result.libraryCount = readUint32();
     // Library offsets are used for start and end offsets, so there is one extra
     // element that this the end offset of the last library
     result.libraryOffsets = new List<int>(result.libraryCount + 1);
-    result.programFileSizeInBytes = readUint32();
-    if (result.programFileSizeInBytes != programFileSize) {
-      throw 'Malformed binary: This program files program index indicates that'
-          ' the filesize should be $programFileSize but other program indexes'
+    result.componentFileSizeInBytes = readUint32();
+    if (result.componentFileSizeInBytes != componentFileSize) {
+      throw 'Malformed binary: This component file\'s component index indicates that'
+          ' the filesize should be $componentFileSize but other component indexes'
           ' has indicated that the size should be '
-          '${result.programFileSizeInBytes}.';
+          '${result.componentFileSizeInBytes}.';
     }
 
     // Skip to the start of the index.
@@ -424,14 +424,14 @@
     // source table offset. That's 6 fields + number of libraries.
     _byteOffset -= (result.libraryCount + 8) * 4;
 
-    // Now read the program index.
-    result.binaryOffsetForSourceTable = _programStartOffset + readUint32();
-    result.binaryOffsetForCanonicalNames = _programStartOffset + readUint32();
-    result.binaryOffsetForStringTable = _programStartOffset + readUint32();
-    result.binaryOffsetForConstantTable = _programStartOffset + readUint32();
+    // Now read the component index.
+    result.binaryOffsetForSourceTable = _componentStartOffset + readUint32();
+    result.binaryOffsetForCanonicalNames = _componentStartOffset + readUint32();
+    result.binaryOffsetForStringTable = _componentStartOffset + readUint32();
+    result.binaryOffsetForConstantTable = _componentStartOffset + readUint32();
     result.mainMethodReference = readUint32();
     for (int i = 0; i < result.libraryCount + 1; ++i) {
-      result.libraryOffsets[i] = _programStartOffset + readUint32();
+      result.libraryOffsets[i] = _componentStartOffset + readUint32();
     }
 
     _byteOffset = savedByteIndex;
@@ -439,11 +439,11 @@
     return result;
   }
 
-  void _readOneProgram(Program program, int programFileSize) {
-    _programStartOffset = _byteOffset;
+  void _readOneComponent(Component component, int componentFileSize) {
+    _componentStartOffset = _byteOffset;
 
     final int magic = readUint32();
-    if (magic != Tag.ProgramFile) {
+    if (magic != Tag.ComponentFile) {
       throw fail('This is not a binary dart file. '
           'Magic number was: ${magic.toRadixString(16)}');
     }
@@ -454,21 +454,22 @@
           '(found ${formatVersion}, expected ${Tag.BinaryFormatVersion})');
     }
 
-    // Read program index from the end of this ProgramFiles serialized data.
-    _ProgramIndex index = _readProgramIndex(programFileSize);
+    // Read component index from the end of this ComponentFiles serialized data.
+    _ComponentIndex index = _readComponentIndex(componentFileSize);
 
     _byteOffset = index.binaryOffsetForStringTable;
     readStringTable(_stringTable);
 
     _byteOffset = index.binaryOffsetForCanonicalNames;
-    readLinkTable(program.root);
+    readLinkTable(component.root);
 
     _byteOffset = index.binaryOffsetForStringTable;
-    _disableLazyReading = _readMetadataSection(program) || _disableLazyReading;
+    _disableLazyReading =
+        _readMetadataSection(component) || _disableLazyReading;
 
     _byteOffset = index.binaryOffsetForSourceTable;
     Map<Uri, Source> uriToSource = readUriToSource();
-    program.uriToSource.addAll(uriToSource);
+    component.uriToSource.addAll(uriToSource);
 
     _byteOffset = index.binaryOffsetForConstantTable;
     readConstantTable();
@@ -476,16 +477,16 @@
     int numberOfLibraries = index.libraryCount;
     for (int i = 0; i < numberOfLibraries; ++i) {
       _byteOffset = index.libraryOffsets[i];
-      readLibrary(program, index.libraryOffsets[i + 1]);
+      readLibrary(component, index.libraryOffsets[i + 1]);
     }
 
     var mainMethod =
         getMemberReferenceFromInt(index.mainMethodReference, allowNull: true);
-    program.mainMethodName ??= mainMethod;
+    component.mainMethodName ??= mainMethod;
 
-    _processPendingMetadataAssociations(program);
+    _processPendingMetadataAssociations(component);
 
-    _byteOffset = _programStartOffset + programFileSize;
+    _byteOffset = _componentStartOffset + componentFileSize;
   }
 
   Map<Uri, Source> readUriToSource() {
@@ -574,7 +575,7 @@
     }
   }
 
-  Library readLibrary(Program program, int endOffset) {
+  Library readLibrary(Component component, int endOffset) {
     // Read index.
     int savedByteOffset = _byteOffset;
 
@@ -588,7 +589,7 @@
     _byteOffset = endOffset - (procedureCount + 3) * 4;
     int classCount = readUint32();
     for (int i = 0; i < procedureCount + 1; i++) {
-      procedureOffsets[i] = _programStartOffset + readUint32();
+      procedureOffsets[i] = _componentStartOffset + readUint32();
     }
     List<int> classOffsets = new List<int>(classCount + 1);
 
@@ -597,7 +598,7 @@
     // (i.e. procedure count + class count + 4 fields).
     _byteOffset = endOffset - (procedureCount + classCount + 4) * 4;
     for (int i = 0; i < classCount + 1; i++) {
-      classOffsets[i] = _programStartOffset + readUint32();
+      classOffsets[i] = _componentStartOffset + readUint32();
     }
     _byteOffset = savedByteOffset;
 
@@ -611,7 +612,7 @@
     if (library == null) {
       library =
           new Library(Uri.parse(canonicalName.name), reference: reference);
-      program.libraries.add(library..parent = program);
+      component.libraries.add(library..parent = component);
     }
     _currentLibrary = library;
     String name = readStringOrNullIfEmpty();
@@ -714,8 +715,8 @@
   }
 
   LibraryPart readLibraryPart(Library library) {
-    var annotations = readExpressionList();
     var fileUri = readUriReference();
+    var annotations = readExpressionList();
     return new LibraryPart(annotations, fileUri)..parent = library;
   }
 
@@ -727,9 +728,9 @@
     if (node == null) {
       node = new Typedef(null, null, reference: reference);
     }
+    Uri fileUri = readUriReference();
     int fileOffset = readOffset();
     String name = readStringReference();
-    Uri fileUri = readUriReference();
     node.annotations = readAnnotationList(node);
     readAndPushTypeParameterList(node.typeParameters, node);
     var type = readDartType();
@@ -757,7 +758,7 @@
     // offsets (i.e. procedure count + 2 fields).
     _byteOffset = endOffset - (procedureCount + 2) * 4;
     for (int i = 0; i < procedureCount + 1; i++) {
-      procedureOffsets[i] = _programStartOffset + readUint32();
+      procedureOffsets[i] = _componentStartOffset + readUint32();
     }
     _byteOffset = savedByteOffset;
 
@@ -768,6 +769,8 @@
     if (node == null) {
       node = new Class(reference: reference)..level = ClassLevel.Temporary;
     }
+
+    var fileUri = readUriReference();
     node.fileOffset = readOffset();
     node.fileEndOffset = readOffset();
     int flags = readByte();
@@ -780,7 +783,6 @@
       node.level = level;
     }
     var name = readStringOrNullIfEmpty();
-    var fileUri = readUriReference();
     var annotations = readAnnotationList(node);
     assert(() {
       debugPath.add(node.name ?? 'normal-class');
@@ -840,12 +842,12 @@
     if (node == null) {
       node = new Field(null, reference: reference);
     }
+    var fileUri = readUriReference();
     int fileOffset = readOffset();
     int fileEndOffset = readOffset();
     int flags = readByte();
     int flags2 = readByte();
     var name = readName();
-    var fileUri = readUriReference();
     var annotations = readAnnotationList(node);
     assert(() {
       debugPath.add(node.name?.name ?? 'field');
@@ -881,11 +883,11 @@
     if (node == null) {
       node = new Constructor(null, reference: reference);
     }
+    var fileUri = readUriReference();
     var fileOffset = readOffset();
     var fileEndOffset = readOffset();
     var flags = readByte();
     var name = readName();
-    var fileUri = readUriReference();
     var annotations = readAnnotationList(node);
     assert(() {
       debugPath.add(node.name?.name ?? 'constructor');
@@ -925,13 +927,13 @@
     if (node == null) {
       node = new Procedure(null, null, null, reference: reference);
     }
+    var fileUri = readUriReference();
     var fileOffset = readOffset();
     var fileEndOffset = readOffset();
     int kindIndex = readByte();
     var kind = ProcedureKind.values[kindIndex];
     var flags = readByte();
     var name = readName();
-    var fileUri = readUriReference();
     var annotations = readAnnotationList(node);
     assert(() {
       debugPath.add(node.name?.name ?? 'procedure');
@@ -982,11 +984,11 @@
     if (node == null) {
       node = new RedirectingFactoryConstructor(null, reference: reference);
     }
+    var fileUri = readUriReference();
     var fileOffset = readOffset();
     var fileEndOffset = readOffset();
     var flags = readByte();
     var name = readName();
-    var fileUri = readUriReference();
     var annotations = readAnnotationList(node);
     debugPath.add(node.name?.name ?? 'redirecting-factory-constructor');
     var targetReference = readMemberReference();
@@ -1106,7 +1108,7 @@
   void _setLazyLoadFunction(FunctionNode result, int oldLabelStackBase,
       int variableStackHeight, int typeParameterStackHeight) {
     final int savedByteOffset = _byteOffset;
-    final int programStartOffset = _programStartOffset;
+    final int componentStartOffset = _componentStartOffset;
     final List<TypeParameter> typeParameters = typeParameterStack.toList();
     final List<VariableDeclaration> variables = variableStack.toList();
     final Library currentLibrary = _currentLibrary;
@@ -1117,7 +1119,7 @@
       typeParameterStack.addAll(typeParameters);
       variableStack.clear();
       variableStack.addAll(variables);
-      _programStartOffset = programStartOffset;
+      _componentStartOffset = componentStartOffset;
 
       result.body = readStatementOption();
       result.body?.parent = result;
@@ -1467,6 +1469,8 @@
         return new ExpressionStatement(readExpression());
       case Tag.Block:
         return readBlock();
+      case Tag.AssertBlock:
+        return readAssertBlock();
       case Tag.EmptyStatement:
         return new EmptyStatement();
       case Tag.AssertStatement:
@@ -1611,6 +1615,13 @@
     return new Block(body);
   }
 
+  AssertBlock readAssertBlock() {
+    int stackHeight = variableStack.length;
+    var body = readStatementList();
+    variableStack.length = stackHeight;
+    return new AssertBlock(body);
+  }
+
   Supertype readSupertype() {
     InterfaceType type = readDartType();
     return new Supertype.byReference(type.className, type.typeArguments);
@@ -1820,7 +1831,7 @@
       : super(bytes, filename: filename);
 
   @override
-  bool _readMetadataSection(Program program) {
+  bool _readMetadataSection(Component component) {
     bool containsNodeReferences = false;
 
     // At the beginning of this function _byteOffset points right past
@@ -1846,7 +1857,7 @@
       // UInt32 tag (fixed size StringReference)
       final tag = _stringTable[readUint32()];
 
-      final repository = program.metadata[tag];
+      final repository = component.metadata[tag];
       if (repository != null) {
         // Read nodeReferences (if any).
         Map<int, int> offsetToReferenceId;
@@ -1884,12 +1895,12 @@
   }
 
   @override
-  void _processPendingMetadataAssociations(Program program) {
+  void _processPendingMetadataAssociations(Component component) {
     if (_subsections == null) {
       return;
     }
 
-    _associateMetadata(program, _programStartOffset);
+    _associateMetadata(component, _componentStartOffset);
 
     for (var subsection in _subsections) {
       if (subsection.pending == null) {
@@ -1959,9 +1970,9 @@
   }
 
   @override
-  Library readLibrary(Program program, int endOffset) {
+  Library readLibrary(Component component, int endOffset) {
     final nodeOffset = _byteOffset;
-    final result = super.readLibrary(program, endOffset);
+    final result = super.readLibrary(component, endOffset);
     return _associateMetadata(result, nodeOffset);
   }
 
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index fb19994..c829ca2 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -190,12 +190,22 @@
     type.accept(this);
   }
 
-  void writeUriReference(Uri uri) {
-    int index = 0; // equivalent to index = _sourceUriIndexer[""];
+  // The currently active file uri where we are writing [TreeNode]s from.  If
+  // this is set to `null` we cannot write file offsets.  The [writeOffset]
+  // helper function will ensure this.
+  Uri _activeFileUri;
+
+  // Returns the new active file uri.
+  Uri writeUriReference(Uri uri) {
     if (_knownSourceUri.contains(uri)) {
-      index = _sourceUriIndexer.put(uri == null ? "" : "$uri");
+      final int index = _sourceUriIndexer.put(uri == null ? "" : "$uri");
+      writeUInt30(index);
+      return uri;
+    } else {
+      final int index = 0; // equivalent to index = _sourceUriIndexer[""];
+      writeUInt30(index);
+      return null;
     }
-    writeUInt30(index);
   }
 
   void writeList<T>(List<T> items, void writeItem(T x)) {
@@ -237,12 +247,12 @@
     }
   }
 
-  void writeLinkTable(Program program) {
+  void writeLinkTable(Component component) {
     _binaryOffsetForLinkTable = getBufferOffset();
     writeList(_canonicalNameList, writeCanonicalNameEntry);
   }
 
-  void indexLinkTable(Program program) {
+  void indexLinkTable(Component component) {
     _canonicalNameList = <CanonicalName>[];
     void visitCanonicalName(CanonicalName node) {
       node.index = _canonicalNameList.length;
@@ -250,20 +260,20 @@
       node.children.forEach(visitCanonicalName);
     }
 
-    for (var library in program.libraries) {
+    for (var library in component.libraries) {
       if (!shouldWriteLibraryCanonicalNames(library)) continue;
       visitCanonicalName(library.canonicalName);
       _knownCanonicalNameNonRootTops.add(library.canonicalName);
     }
   }
 
-  /// Compute canonical names for the whole program or parts of it.
-  void computeCanonicalNames(Program program) {
-    program.computeCanonicalNames();
+  /// Compute canonical names for the whole component or parts of it.
+  void computeCanonicalNames(Component component) {
+    component.computeCanonicalNames();
   }
 
   /// Return `true` if all canonical names of the [library] should be written
-  /// into the link table.  If some libraries of the program are skipped,
+  /// into the link table.  If some libraries of the component are skipped,
   /// then all the additional names referenced by the libraries that are written
   /// by [writeLibraries] are automatically added.
   bool shouldWriteLibraryCanonicalNames(Library library) => true;
@@ -278,31 +288,31 @@
     writeStringReference(node.name);
   }
 
-  void writeProgramFile(Program program) {
-    computeCanonicalNames(program);
-    final programOffset = getBufferOffset();
-    writeUInt32(Tag.ProgramFile);
+  void writeComponentFile(Component component) {
+    computeCanonicalNames(component);
+    final componentOffset = getBufferOffset();
+    writeUInt32(Tag.ComponentFile);
     writeUInt32(Tag.BinaryFormatVersion);
-    indexLinkTable(program);
-    indexUris(program);
-    // Note: must write metadata payloads before any other node in the program
+    indexLinkTable(component);
+    indexUris(component);
+    // Note: must write metadata payloads before any other node in the component
     // to collect references to nodes contained within metadata payloads.
-    _writeMetadataPayloads(program);
+    _writeMetadataPayloads(component);
     if (_metadataSubsections != null) {
-      _recordNodeOffsetForMetadataMappingImpl(program, programOffset);
+      _recordNodeOffsetForMetadataMappingImpl(component, componentOffset);
     }
     libraryOffsets = <int>[];
-    CanonicalName main = getCanonicalNameOfMember(program.mainMethod);
+    CanonicalName main = getCanonicalNameOfMember(component.mainMethod);
     if (main != null) {
       checkCanonicalName(main);
     }
-    writeLibraries(program);
-    writeUriToSource(program.uriToSource);
-    writeLinkTable(program);
-    _writeMetadataMappingSection(program);
+    writeLibraries(component);
+    writeUriToSource(component.uriToSource);
+    writeLinkTable(component);
+    _writeMetadataMappingSection(component);
     writeStringTable(stringIndexer);
     writeConstantTable(_constantIndexer);
-    writeProgramIndex(program, program.libraries);
+    writeComponentIndex(component, component.libraries);
 
     _flush();
   }
@@ -323,16 +333,16 @@
   }
 
   /// Collect and write out all metadata contained in metadata repositories
-  /// associated with the program.
+  /// associated with the component.
   ///
   /// Non-empty metadata subsections will be collected in [_metadataSubsections]
-  /// and used to generate metadata mappings after all nodes in the program
+  /// and used to generate metadata mappings after all nodes in the component
   /// are written and all node offsets are known.
   ///
-  /// Note: must write metadata payloads before any other node in the program
+  /// Note: must write metadata payloads before any other node in the component
   /// to collect references to nodes contained within metadata payloads.
-  void _writeMetadataPayloads(Program program) {
-    program.metadata.forEach((tag, repository) {
+  void _writeMetadataPayloads(Component component) {
+    component.metadata.forEach((tag, repository) {
       if (repository.mapping.isEmpty) {
         return;
       }
@@ -379,13 +389,13 @@
     }
   }
 
-  void _writeMetadataMappingSection(Program program) {
+  void _writeMetadataMappingSection(Component component) {
     if (_metadataSubsections == null) {
       writeUInt32(0); // Empty section.
       return;
     }
 
-    _recordNodeOffsetForMetadataMappingImpl(program, 0);
+    _recordNodeOffsetForMetadataMappingImpl(component, 0);
 
     // RList<MetadataMapping> metadataMappings
     for (var subsection in _metadataSubsections) {
@@ -413,12 +423,12 @@
     writeUInt32(_metadataSubsections.length);
   }
 
-  /// Write all of some of the libraries of the [program].
-  void writeLibraries(Program program) {
-    program.libraries.forEach(writeNode);
+  /// Write all of some of the libraries of the [component].
+  void writeLibraries(Component component) {
+    component.libraries.forEach(writeNode);
   }
 
-  void writeProgramIndex(Program program, List<Library> libraries) {
+  void writeComponentIndex(Component component, List<Library> libraries) {
     // Fixed-size ints at the end used as an index.
     assert(_binaryOffsetForSourceTable >= 0);
     writeUInt32(_binaryOffsetForSourceTable);
@@ -429,7 +439,7 @@
     assert(_binaryOffsetForConstantTable >= 0);
     writeUInt32(_binaryOffsetForConstantTable);
 
-    CanonicalName main = getCanonicalNameOfMember(program.mainMethod);
+    CanonicalName main = getCanonicalNameOfMember(component.mainMethod);
     if (main == null) {
       writeUInt32(0);
     } else {
@@ -446,8 +456,8 @@
     writeUInt32(getBufferOffset() + 4); // total size.
   }
 
-  void indexUris(Program program) {
-    _knownSourceUri.addAll(program.uriToSource.keys);
+  void indexUris(Component component) {
+    _knownSourceUri.addAll(component.uriToSource.keys);
   }
 
   void writeUriToSource(Map<Uri, Source> uriToSource) {
@@ -528,6 +538,10 @@
   }
 
   writeOffset(int offset) {
+    if (_activeFileUri == null) {
+      offset = TreeNode.noOffset;
+    }
+
     // TODO(jensj): Delta-encoding.
     // File offset ranges from -1 and up,
     // but is here saved as unsigned (thus the +1)
@@ -569,7 +583,10 @@
     writeCanonicalNameReference(getCanonicalNameOfLibrary(node));
     writeStringReference(node.name ?? '');
     // TODO(jensj): We save (almost) the same URI twice.
-    writeUriReference(node.fileUri);
+
+    final Uri activeFileUriSaved = _activeFileUri;
+    _activeFileUri = writeUriReference(node.fileUri);
+
     writeAnnotationList(node.annotations);
     writeLibraryDependencies(node);
     writeAdditionalExports(node.additionalExports);
@@ -583,6 +600,8 @@
     writeNodeList(node.procedures);
     procedureOffsets.add(getBufferOffset());
 
+    _activeFileUri = activeFileUriSaved;
+
     // Fixed-size ints at the end used as an index.
     assert(classOffsets.length > 0);
     for (int offset in classOffsets) {
@@ -645,20 +664,27 @@
     if (_metadataSubsections != null) {
       _recordNodeOffsetForMetadataMapping(node);
     }
+    final Uri activeFileUriSaved = _activeFileUri;
+    _activeFileUri = writeUriReference(node.fileUri);
     writeNodeList(node.annotations);
-    writeUriReference(node.fileUri);
+    _activeFileUri = activeFileUriSaved;
   }
 
   void visitTypedef(Typedef node) {
     writeCanonicalNameReference(getCanonicalNameOfTypedef(node));
+
+    final Uri activeFileUriSaved = _activeFileUri;
+    _activeFileUri = writeUriReference(node.fileUri);
+
     writeOffset(node.fileOffset);
     writeStringReference(node.name);
-    writeUriReference(node.fileUri);
     writeAnnotationList(node.annotations);
     _typeParameterIndexer.enter(node.typeParameters);
     writeNodeList(node.typeParameters);
     writeNode(node.type);
     _typeParameterIndexer.exit(node.typeParameters);
+
+    _activeFileUri = activeFileUriSaved;
   }
 
   void writeAnnotation(Expression annotation) {
@@ -698,11 +724,15 @@
     }
     writeByte(Tag.Class);
     writeCanonicalNameReference(getCanonicalNameOfClass(node));
+
+    final Uri activeFileUriSaved = _activeFileUri;
+    _activeFileUri = writeUriReference(node.fileUri);
+
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeByte(flags);
     writeStringReference(node.name ?? '');
-    writeUriReference(node.fileUri);
+
     writeAnnotationList(node.annotations);
     _typeParameterIndexer.enter(node.typeParameters);
     writeNodeList(node.typeParameters);
@@ -717,6 +747,8 @@
     writeNodeList(node.redirectingFactoryConstructors);
     _typeParameterIndexer.exit(node.typeParameters);
 
+    _activeFileUri = activeFileUriSaved;
+
     assert(procedureOffsets.length > 0);
     for (int offset in procedureOffsets) {
       writeUInt32(offset);
@@ -733,11 +765,15 @@
     _variableIndexer = new VariableIndexer();
     writeByte(Tag.Constructor);
     writeCanonicalNameReference(getCanonicalNameOfMember(node));
+
+    final Uri activeFileUriSaved = _activeFileUri;
+    _activeFileUri = writeUriReference(node.fileUri);
+
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeByte(node.flags);
     writeName(node.name ?? _emptyName);
-    writeUriReference(node.fileUri);
+
     writeAnnotationList(node.annotations);
     assert(node.function.typeParameters.isEmpty);
     writeNode(node.function);
@@ -745,6 +781,9 @@
     _variableIndexer.restoreScope(node.function.positionalParameters.length +
         node.function.namedParameters.length);
     writeNodeList(node.initializers);
+
+    _activeFileUri = activeFileUriSaved;
+
     _variableIndexer = null;
   }
 
@@ -757,16 +796,22 @@
     _variableIndexer = new VariableIndexer();
     writeByte(Tag.Procedure);
     writeCanonicalNameReference(getCanonicalNameOfMember(node));
+
+    final Uri activeFileUriSaved = _activeFileUri;
+    _activeFileUri = writeUriReference(node.fileUri);
+
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeByte(node.kind.index);
     writeByte(node.flags);
     writeName(node.name ?? '');
-    writeUriReference(node.fileUri);
     writeAnnotationList(node.annotations);
     writeOptionalReference(node.forwardingStubSuperTargetReference);
     writeOptionalReference(node.forwardingStubInterfaceTargetReference);
     writeOptionalNode(node.function);
+
+    _activeFileUri = activeFileUriSaved;
+
     _variableIndexer = null;
 
     assert((node.forwardingStubSuperTarget != null) ||
@@ -780,15 +825,21 @@
     _variableIndexer = new VariableIndexer();
     writeByte(Tag.Field);
     writeCanonicalNameReference(getCanonicalNameOfMember(node));
+
+    final Uri activeFileUriSaved = _activeFileUri;
+    _activeFileUri = writeUriReference(node.fileUri);
+
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeByte(node.flags);
     writeByte(node.flags2);
     writeName(node.name);
-    writeUriReference(node.fileUri);
     writeAnnotationList(node.annotations);
     writeNode(node.type);
     writeOptionalNode(node.initializer);
+
+    _activeFileUri = activeFileUriSaved;
+
     _variableIndexer = null;
   }
 
@@ -801,11 +852,15 @@
     _variableIndexer.pushScope();
     _typeParameterIndexer.enter(node.typeParameters);
     writeCanonicalNameReference(getCanonicalNameOfMember(node));
+
+    final Uri activeFileUriSaved = _activeFileUri;
+    _activeFileUri = writeUriReference(node.fileUri);
+
     writeOffset(node.fileOffset);
     writeOffset(node.fileEndOffset);
     writeByte(node.flags);
     writeName(node.name);
-    writeUriReference(node.fileUri);
+
     writeAnnotationList(node.annotations);
     writeReference(node.targetReference);
     writeNodeList(node.typeArguments);
@@ -815,6 +870,9 @@
     writeVariableDeclarationList(node.positionalParameters);
     writeVariableDeclarationList(node.namedParameters);
     _typeParameterIndexer.exit(node.typeParameters);
+
+    _activeFileUri = activeFileUriSaved;
+
     _variableIndexer.popScope();
     _variableIndexer = null;
   }
@@ -1273,6 +1331,13 @@
     _variableIndexer.popScope();
   }
 
+  visitAssertBlock(AssertBlock node) {
+    _variableIndexer.pushScope();
+    writeByte(Tag.AssertBlock);
+    writeNodeList(node.statements);
+    _variableIndexer.popScope();
+  }
+
   visitEmptyStatement(EmptyStatement node) {
     writeByte(Tag.EmptyStatement);
   }
@@ -1759,7 +1824,7 @@
     }
   }
 
-  visitProgram(Program node) {
+  visitComponent(Component node) {
     buildIndexForList(node.libraries);
   }
 
diff --git a/pkg/kernel/lib/binary/limited_ast_to_binary.dart b/pkg/kernel/lib/binary/limited_ast_to_binary.dart
index 110da9a..82fe07d 100644
--- a/pkg/kernel/lib/binary/limited_ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/limited_ast_to_binary.dart
@@ -8,7 +8,7 @@
 /// Writes libraries that satisfy the [predicate].
 ///
 /// Only the referenced subset of canonical names is indexed and written,
-/// so we don't waste time indexing all libraries of a program, when only
+/// so we don't waste time indexing all libraries of a component, when only
 /// a tiny subset is used.
 class LimitedBinaryPrinter extends BinaryPrinter {
   final LibraryFilter predicate;
@@ -27,10 +27,10 @@
       : super(sink);
 
   @override
-  void computeCanonicalNames(Program program) {
-    for (var library in program.libraries) {
+  void computeCanonicalNames(Component component) {
+    for (var library in component.libraries) {
       if (predicate(library)) {
-        program.root
+        component.root
             .getChildFromUri(library.importUri)
             .bindTo(library.reference);
         library.computeCanonicalNames();
@@ -44,8 +44,8 @@
   }
 
   @override
-  void writeLibraries(Program program) {
-    var librariesToWrite = program.libraries.where(predicate).toList();
+  void writeLibraries(Component component) {
+    var librariesToWrite = component.libraries.where(predicate).toList();
     writeList(librariesToWrite, writeNode);
   }
 
@@ -56,15 +56,15 @@
   }
 
   @override
-  void writeProgramIndex(Program program, List<Library> libraries) {
+  void writeComponentIndex(Component component, List<Library> libraries) {
     var librariesToWrite = libraries.where(predicate).toList();
-    super.writeProgramIndex(program, librariesToWrite);
+    super.writeComponentIndex(component, librariesToWrite);
   }
 
   @override
-  void indexUris(Program program) {
+  void indexUris(Component component) {
     if (!excludeUriToSource) {
-      super.indexUris(program);
+      super.indexUris(component);
     } else {
       // We pretend not to know any uris, thereby excluding all sources.
     }
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 2380ad9..b58cda9 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -91,6 +91,7 @@
   static const int VariableDeclaration = 78;
   static const int FunctionDeclaration = 79;
   static const int AsyncForInStatement = 80;
+  static const int AssertBlock = 81;
 
   static const int TypedefType = 87;
   static const int VectorType = 88;
@@ -129,7 +130,7 @@
 
   static const int SpecializedIntLiteralBias = 3;
 
-  static const int ProgramFile = 0x90ABCDEF;
+  static const int ComponentFile = 0x90ABCDEF;
 
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 05ba206..20eadbe 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -20,11 +20,11 @@
 /// TODO(scheglov) Several methods are not used, or used only in tests.
 /// Check if these methods are not useful and should be removed .
 abstract class ClassHierarchy {
-  factory ClassHierarchy(Program program,
+  factory ClassHierarchy(Component component,
       {HandleAmbiguousSupertypes onAmbiguousSupertypes,
       MixinInferrer mixinInferrer}) {
     int numberOfClasses = 0;
-    for (var library in program.libraries) {
+    for (var library in component.libraries) {
       numberOfClasses += library.classes.length;
     }
     onAmbiguousSupertypes ??= (Class cls, Supertype a, Supertype b) {
@@ -34,7 +34,7 @@
       }
     };
     return new ClosedWorldClassHierarchy._internal(
-        program, numberOfClasses, onAmbiguousSupertypes)
+        component, numberOfClasses, onAmbiguousSupertypes)
       .._initialize(mixinInferrer);
   }
 
@@ -46,7 +46,7 @@
   /// Returns the unique index of the [class_].
   int getClassIndex(Class class_);
 
-  /// True if the program contains another class that is a subtype of given one.
+  /// True if the component contains another class that is a subtype of given one.
   bool hasProperSubtypes(Class class_);
 
   /// Returns the number of steps in the longest inheritance path from [class_]
@@ -332,10 +332,10 @@
 class ClosedWorldClassHierarchy implements ClassHierarchy {
   final HandleAmbiguousSupertypes _onAmbiguousSupertypes;
 
-  /// The [Program] that this class hierarchy represents.
-  final Program _program;
+  /// The [Component] that this class hierarchy represents.
+  final Component _component;
 
-  /// All classes in the program.
+  /// All classes in the component.
   ///
   /// The list is ordered so that classes occur after their super classes.
   final List<Class> classes;
@@ -346,7 +346,7 @@
   final List<Class> _classesByTopDownIndex;
 
   ClosedWorldClassHierarchy._internal(
-      this._program, int numberOfClasses, this._onAmbiguousSupertypes)
+      this._component, int numberOfClasses, this._onAmbiguousSupertypes)
       : classes = new List<Class>(numberOfClasses),
         _classesByTopDownIndex = new List<Class>(numberOfClasses);
 
@@ -680,7 +680,7 @@
   @override
   ClassHierarchy applyChanges(Iterable<Class> classes) {
     if (classes.isEmpty) return this;
-    return new ClassHierarchy(_program,
+    return new ClassHierarchy(_component,
         onAmbiguousSupertypes: _onAmbiguousSupertypes);
   }
 
@@ -700,7 +700,7 @@
 
   void _initialize(MixinInferrer mixinInferrer) {
     // Build the class ordering based on a topological sort.
-    for (var library in _program.libraries) {
+    for (var library in _component.libraries) {
       for (var classNode in library.classes) {
         _topologicalSortVisit(classNode);
       }
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index 0d4982d..3eb51ac 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -41,12 +41,33 @@
     throw 'Cloning of classes is not implemented';
   }
 
-  TreeNode clone(TreeNode node) =>
-      node.accept(this)..fileOffset = node.fileOffset;
+  // The currently active file uri where we are cloning [TreeNode]s from.  If
+  // this is set to `null` we cannot clone file offsets to newly created nodes.
+  // The [_cloneFileOffset] helper function will ensure this.
+  Uri _activeFileUri;
+
+  // If we don't know the file uri we are cloning elements from, it's not safe
+  // to clone file offsets either.
+  int _cloneFileOffset(int fileOffset) {
+    return _activeFileUri == null ? TreeNode.noOffset : fileOffset;
+  }
+
+  TreeNode clone(TreeNode node) {
+    final Uri activeFileUriSaved = _activeFileUri;
+    if (node is FileUriNode) _activeFileUri = node.fileUri ?? _activeFileUri;
+    final TreeNode result = node.accept(this)
+      ..fileOffset = _cloneFileOffset(node.fileOffset);
+    _activeFileUri = activeFileUriSaved;
+    return result;
+  }
 
   TreeNode cloneOptional(TreeNode node) {
+    if (node == null) return null;
+    final Uri activeFileUriSaved = _activeFileUri;
+    if (node is FileUriNode) _activeFileUri = node.fileUri ?? _activeFileUri;
     TreeNode result = node?.accept(this);
-    if (result != null) result.fileOffset = node.fileOffset;
+    if (result != null) result.fileOffset = _cloneFileOffset(node.fileOffset);
+    _activeFileUri = activeFileUriSaved;
     return result;
   }
 
@@ -279,6 +300,10 @@
     return new Block(node.statements.map(clone).toList());
   }
 
+  visitAssertBlock(AssertBlock node) {
+    return new AssertBlock(node.statements.map(clone).toList());
+  }
+
   visitEmptyStatement(EmptyStatement node) {
     return new EmptyStatement();
   }
@@ -390,8 +415,10 @@
         isExternal: node.isExternal,
         isSynthetic: node.isSynthetic,
         initializers: node.initializers.map(clone).toList(),
-        transformerFlags: node.transformerFlags)
-      ..fileEndOffset = node.fileEndOffset;
+        transformerFlags: node.transformerFlags,
+        fileUri: _activeFileUri)
+      ..fileOffset = _cloneFileOffset(node.fileOffset)
+      ..fileEndOffset = _cloneFileOffset(node.fileEndOffset);
   }
 
   visitProcedure(Procedure node) {
@@ -403,10 +430,11 @@
         isForwardingStub: node.isForwardingStub,
         isForwardingSemiStub: node.isForwardingSemiStub,
         transformerFlags: node.transformerFlags,
-        fileUri: node.fileUri,
+        fileUri: _activeFileUri,
         forwardingStubSuperTarget: node.forwardingStubSuperTarget,
         forwardingStubInterfaceTarget: node.forwardingStubInterfaceTarget)
-      ..fileEndOffset = node.fileEndOffset
+      ..fileOffset = _cloneFileOffset(node.fileOffset)
+      ..fileEndOffset = _cloneFileOffset(node.fileEndOffset)
       ..isGenericContravariant = node.isGenericContravariant;
   }
 
@@ -421,8 +449,9 @@
         hasImplicitGetter: node.hasImplicitGetter,
         hasImplicitSetter: node.hasImplicitSetter,
         transformerFlags: node.transformerFlags,
-        fileUri: node.fileUri)
-      ..fileEndOffset = node.fileEndOffset
+        fileUri: _activeFileUri)
+      ..fileOffset = _cloneFileOffset(node.fileOffset)
+      ..fileEndOffset = _cloneFileOffset(node.fileEndOffset)
       ..flags = node.flags
       ..flags2 = node.flags2;
   }
@@ -437,7 +466,8 @@
         typeParameters: node.typeParameters.map(clone).toList(),
         positionalParameters: node.positionalParameters.map(clone).toList(),
         namedParameters: node.namedParameters.map(clone).toList(),
-        requiredParameterCount: node.requiredParameterCount);
+        requiredParameterCount: node.requiredParameterCount,
+        fileUri: _activeFileUri);
   }
 
   visitTypeParameter(TypeParameter node) {
@@ -461,7 +491,8 @@
         returnType: visitType(node.returnType),
         asyncMarker: node.asyncMarker,
         dartAsyncMarker: node.dartAsyncMarker)
-      ..fileEndOffset = node.fileEndOffset;
+      ..fileOffset = _cloneFileOffset(node.fileOffset)
+      ..fileEndOffset = _cloneFileOffset(node.fileEndOffset);
   }
 
   visitArguments(Arguments node) {
@@ -541,7 +572,7 @@
     return new LocalInitializer(clone(node.variable));
   }
 
-  visitProgram(Program node) {
+  visitComponent(Component node) {
     return defaultTreeNode(node);
   }
 
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index fe1cd4b..05f7f6f 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -94,10 +94,11 @@
   Procedure _asyncErrorWrapperHelperProcedure;
   Procedure _awaitHelperProcedure;
 
-  /// The `dart:mirrors` library, or `null` if the program does not use it.
+  /// The `dart:mirrors` library, or `null` if the component does not use it.
   Library _mirrorsLibrary;
 
-  CoreTypes(Program program) : _index = new LibraryIndex.coreLibraries(program);
+  CoreTypes(Component component)
+      : _index = new LibraryIndex.coreLibraries(component);
 
   Procedure get asyncErrorWrapperHelperProcedure {
     return _asyncErrorWrapperHelperProcedure ??=
diff --git a/pkg/kernel/lib/error_formatter.dart b/pkg/kernel/lib/error_formatter.dart
index cdddaba..56f4a9f 100644
--- a/pkg/kernel/lib/error_formatter.dart
+++ b/pkg/kernel/lib/error_formatter.dart
@@ -41,9 +41,9 @@
     if (fileOffset != TreeNode.noOffset) {
       final fileUri = _fileUriOf(context);
 
-      final program = context.enclosingProgram;
-      final source = program.uriToSource[fileUri];
-      final location = program.getLocation(fileUri, fileOffset);
+      final component = context.enclosingComponent;
+      final source = component.uriToSource[fileUri];
+      final location = component.getLocation(fileUri, fileOffset);
       final lineStart = source.lineStarts[location.line - 1];
       final lineEnd = (location.line < source.lineStarts.length)
           ? source.lineStarts[location.line]
diff --git a/pkg/kernel/lib/import_table.dart b/pkg/kernel/lib/import_table.dart
index baadca4..ae2829c 100644
--- a/pkg/kernel/lib/import_table.dart
+++ b/pkg/kernel/lib/import_table.dart
@@ -10,12 +10,12 @@
   int getImportIndex(Library library);
 }
 
-class ProgramImportTable implements ImportTable {
+class ComponentImportTable implements ImportTable {
   final Map<Library, int> _libraryIndex = <Library, int>{};
 
-  ProgramImportTable(Program program) {
-    for (int i = 0; i < program.libraries.length; ++i) {
-      _libraryIndex[program.libraries[i]] = i;
+  ComponentImportTable(Component component) {
+    for (int i = 0; i < component.libraries.length; ++i) {
+      _libraryIndex[component.libraries[i]] = i;
     }
   }
 
diff --git a/pkg/kernel/lib/interpreter/interpreter.dart b/pkg/kernel/lib/interpreter/interpreter.dart
index ef47e93..598d400 100644
--- a/pkg/kernel/lib/interpreter/interpreter.dart
+++ b/pkg/kernel/lib/interpreter/interpreter.dart
@@ -22,14 +22,14 @@
   static MainEnvironment mainEnvironment =
       new MainEnvironment(<Member, Location>{});
 
-  final Program program;
+  final Component component;
   final StatementExecuter visitor = new StatementExecuter();
 
-  Interpreter(this.program);
+  Interpreter(this.component);
 
   void run() {
-    assert(program.libraries.isEmpty);
-    Procedure mainMethod = program.mainMethod;
+    assert(component.libraries.isEmpty);
+    Procedure mainMethod = component.mainMethod;
 
     if (mainMethod == null) return;
 
diff --git a/pkg/kernel/lib/kernel.dart b/pkg/kernel/lib/kernel.dart
index e3c04e1..5ffbd41 100644
--- a/pkg/kernel/lib/kernel.dart
+++ b/pkg/kernel/lib/kernel.dart
@@ -22,18 +22,18 @@
 
 export 'ast.dart';
 
-Program loadProgramFromBinary(String path, [Program program]) {
+Component loadComponentFromBinary(String path, [Component component]) {
   List<int> bytes = new File(path).readAsBytesSync();
-  return loadProgramFromBytes(bytes, program);
+  return loadComponentFromBytes(bytes, component);
 }
 
-Program loadProgramFromBytes(List<int> bytes, [Program program]) {
-  program ??= new Program();
-  new BinaryBuilder(bytes).readProgram(program);
-  return program;
+Component loadComponentFromBytes(List<int> bytes, [Component component]) {
+  component ??= new Component();
+  new BinaryBuilder(bytes).readComponent(component);
+  return component;
 }
 
-Future writeProgramToBinary(Program program, String path) {
+Future writeComponentToBinary(Component component, String path) {
   var sink;
   if (path == 'null' || path == 'stdout') {
     sink = stdout.nonBlocking;
@@ -43,7 +43,7 @@
 
   var future;
   try {
-    new BinaryPrinter(sink).writeProgramFile(program);
+    new BinaryPrinter(sink).writeComponentFile(component);
   } finally {
     if (sink == stdout.nonBlocking) {
       future = sink.flush();
@@ -65,7 +65,7 @@
   }
 }
 
-void writeProgramToText(Program program,
+void writeComponentToText(Component component,
     {String path,
     bool showExternal: false,
     bool showOffsets: false,
@@ -75,7 +75,7 @@
           showExternal: showExternal,
           showOffsets: showOffsets,
           showMetadata: showMetadata)
-      .writeProgramFile(program);
+      .writeComponentFile(component);
   if (path == null) {
     print(buffer);
   } else {
diff --git a/pkg/kernel/lib/library_index.dart b/pkg/kernel/lib/library_index.dart
index 0708af3..0f5ab16 100644
--- a/pkg/kernel/lib/library_index.dart
+++ b/pkg/kernel/lib/library_index.dart
@@ -20,9 +20,9 @@
   final Map<String, _ClassTable> _libraries = <String, _ClassTable>{};
 
   /// Indexes the libraries with the URIs given in [libraryUris].
-  LibraryIndex(Program program, Iterable<String> libraryUris) {
+  LibraryIndex(Component component, Iterable<String> libraryUris) {
     var libraryUriSet = libraryUris.toSet();
-    for (var library in program.libraries) {
+    for (var library in component.libraries) {
       var uri = '${library.importUri}';
       if (libraryUriSet.contains(uri)) {
         _libraries[uri] = new _ClassTable(library);
@@ -31,24 +31,24 @@
   }
 
   /// Indexes the libraries with the URIs given in [libraryUris].
-  LibraryIndex.byUri(Program program, Iterable<Uri> libraryUris)
-      : this(program, libraryUris.map((uri) => '$uri'));
+  LibraryIndex.byUri(Component component, Iterable<Uri> libraryUris)
+      : this(component, libraryUris.map((uri) => '$uri'));
 
   /// Indexes `dart:` libraries.
-  LibraryIndex.coreLibraries(Program program) {
-    for (var library in program.libraries) {
+  LibraryIndex.coreLibraries(Component component) {
+    for (var library in component.libraries) {
       if (library.importUri.scheme == 'dart') {
         _libraries['${library.importUri}'] = new _ClassTable(library);
       }
     }
   }
 
-  /// Indexes the entire program.
+  /// Indexes the entire component.
   ///
   /// Consider using another constructor to only index the libraries that
   /// are needed.
-  LibraryIndex.all(Program program) {
-    for (var library in program.libraries) {
+  LibraryIndex.all(Component component) {
+    for (var library in component.libraries) {
       _libraries['${library.importUri}'] = new _ClassTable(library);
     }
   }
diff --git a/pkg/kernel/lib/naive_type_checker.dart b/pkg/kernel/lib/naive_type_checker.dart
index 4450bc5f..548e434 100644
--- a/pkg/kernel/lib/naive_type_checker.dart
+++ b/pkg/kernel/lib/naive_type_checker.dart
@@ -17,12 +17,12 @@
 class StrongModeTypeChecker extends type_checker.TypeChecker {
   final FailureListener failures;
 
-  StrongModeTypeChecker(FailureListener failures, Program program,
+  StrongModeTypeChecker(FailureListener failures, Component component,
       {bool ignoreSdk: false})
       : this._(
             failures,
-            new CoreTypes(program),
-            new ClassHierarchy(program,
+            new CoreTypes(component),
+            new ClassHierarchy(component,
                 onAmbiguousSupertypes: (Class cls, Supertype s0, Supertype s1) {
               failures.reportFailure(
                   cls, "$cls can't implement both $s1 and $s1");
diff --git a/pkg/kernel/lib/src/tool/batch_util.dart b/pkg/kernel/lib/src/tool/batch_util.dart
index a758095..c3cccb6 100644
--- a/pkg/kernel/lib/src/tool/batch_util.dart
+++ b/pkg/kernel/lib/src/tool/batch_util.dart
@@ -24,7 +24,7 @@
   int testsFailed = 0;
   var watch = new Stopwatch()..start();
   print('>>> BATCH START');
-  Stream input = stdin.transform(UTF8.decoder).transform(new LineSplitter());
+  Stream input = stdin.transform(utf8.decoder).transform(new LineSplitter());
   await for (String line in input) {
     if (line.isEmpty) {
       int time = watch.elapsedMilliseconds;
diff --git a/pkg/kernel/lib/target/targets.dart b/pkg/kernel/lib/target/targets.dart
index 9eecdb8..22672fd 100644
--- a/pkg/kernel/lib/target/targets.dart
+++ b/pkg/kernel/lib/target/targets.dart
@@ -93,41 +93,41 @@
   bool get enableSuperMixins => false;
 
   /// Perform target-specific transformations on the outlines stored in
-  /// [Program] when generating summaries.
+  /// [Component] when generating summaries.
   ///
   /// This transformation is used to add metadata on outlines and to filter
   /// unnecessary information before generating program summaries. This
   /// transformation is not applied when compiling full kernel programs to
   /// prevent affecting the internal invariants of the compiler and accidentally
   /// slowing down compilation.
-  void performOutlineTransformations(Program program) {}
+  void performOutlineTransformations(Component component) {}
 
-  /// Perform target-specific modular transformations on the given program.
+  /// Perform target-specific modular transformations on the given component.
   ///
-  /// These transformations should not be whole-program transformations.  They
-  /// should expect that the program will contain external libraries.
-  void performModularTransformationsOnProgram(
-      CoreTypes coreTypes, ClassHierarchy hierarchy, Program program,
+  /// These transformations should not be whole-component transformations.  They
+  /// should expect that the component will contain external libraries.
+  void performModularTransformationsOnComponent(
+      CoreTypes coreTypes, ClassHierarchy hierarchy, Component component,
       {void logger(String msg)}) {
     performModularTransformationsOnLibraries(
-        coreTypes, hierarchy, program.libraries,
+        coreTypes, hierarchy, component.libraries,
         logger: logger);
   }
 
   /// Perform target-specific modular transformations on the given libraries.
   ///
   /// The intent of this method is to perform the transformations only on some
-  /// subset of the program libraries and avoid packing them into a temporary
-  /// [Program] instance to pass into [performModularTransformationsOnProgram].
+  /// subset of the component libraries and avoid packing them into a temporary
+  /// [Component] instance to pass into [performModularTransformationsOnComponent].
   ///
   /// Note that the following should be equivalent:
   ///
-  ///     target.performModularTransformationsOnProgram(coreTypes, program);
+  ///     target.performModularTransformationsOnComponent(coreTypes, component);
   ///
   /// and
   ///
   ///     target.performModularTransformationsOnLibraries(
-  ///         coreTypes, program.libraries);
+  ///         coreTypes, component.libraries);
   void performModularTransformationsOnLibraries(
       CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
       {void logger(String msg)});
@@ -138,10 +138,10 @@
   /// correctness.  Everything should work if a simple and fast linker chooses
   /// not to apply these transformations.
   ///
-  /// Note that [performGlobalTransformations] doesn't have -OnProgram and
+  /// Note that [performGlobalTransformations] doesn't have -OnComponent and
   /// -OnLibraries alternatives, because the global knowledge required by the
-  /// transformations is assumed to be retrieved from a [Program] instance.
-  void performGlobalTransformations(CoreTypes coreTypes, Program program,
+  /// transformations is assumed to be retrieved from a [Component] instance.
+  void performGlobalTransformations(CoreTypes coreTypes, Component component,
       {void logger(String msg)});
 
   /// Whether a platform library may define a restricted type, such as `bool`,
@@ -223,7 +223,7 @@
   void performModularTransformationsOnLibraries(
       CoreTypes coreTypes, ClassHierarchy hierarchy, List<Library> libraries,
       {void logger(String msg)}) {}
-  void performGlobalTransformations(CoreTypes coreTypes, Program program,
+  void performGlobalTransformations(CoreTypes coreTypes, Component component,
       {void logger(String msg)}) {}
 
   @override
diff --git a/pkg/kernel/lib/target/vm.dart b/pkg/kernel/lib/target/vm.dart
index 6090179..5fd891e 100644
--- a/pkg/kernel/lib/target/vm.dart
+++ b/pkg/kernel/lib/target/vm.dart
@@ -68,7 +68,7 @@
   }
 
   @override
-  void performGlobalTransformations(CoreTypes coreTypes, Program program,
+  void performGlobalTransformations(CoreTypes coreTypes, Component component,
       {void logger(String msg)}) {}
 
   @override
diff --git a/pkg/kernel/lib/target/vmcc.dart b/pkg/kernel/lib/target/vmcc.dart
index 3496882..a5f6a14 100644
--- a/pkg/kernel/lib/target/vmcc.dart
+++ b/pkg/kernel/lib/target/vmcc.dart
@@ -3,14 +3,15 @@
 // BSD-style license that can be found in the LICENSE file.
 library kernel.target.vmcc;
 
-import '../ast.dart' show Program, Library;
+import '../ast.dart' show Component, Library;
 import '../core_types.dart' show CoreTypes;
 import '../class_hierarchy.dart';
 import '../transformations/continuation.dart' as cont;
 import '../transformations/mixin_full_resolution.dart' as mix;
 import '../transformations/sanitize_for_vm.dart';
 import '../transformations/treeshaker.dart';
-import '../transformations/closure_conversion.dart' as cc show transformProgram;
+import '../transformations/closure_conversion.dart' as cc
+    show transformComponent;
 import 'targets.dart' show TargetFlags;
 import 'vm.dart' as vm_target;
 
@@ -38,23 +39,23 @@
   }
 
   @override
-  void performGlobalTransformations(CoreTypes coreTypes, Program program,
+  void performGlobalTransformations(CoreTypes coreTypes, Component component,
       {void logger(String msg)}) {
     if (flags.treeShake) {
-      performTreeShaking(coreTypes, program);
+      performTreeShaking(coreTypes, component);
     }
 
-    cont.transformProgram(coreTypes, program, flags.syncAsync);
+    cont.transformComponent(coreTypes, component, flags.syncAsync);
 
-    new SanitizeForVM().transform(program);
+    new SanitizeForVM().transform(component);
 
-    cc.transformProgram(coreTypes, program);
+    cc.transformComponent(coreTypes, component);
   }
 
-  void performTreeShaking(CoreTypes coreTypes, Program program) {
-    new TreeShaker(coreTypes, _hierarchy, program,
+  void performTreeShaking(CoreTypes coreTypes, Component component) {
+    new TreeShaker(coreTypes, _hierarchy, component,
             strongMode: strongMode, programRoots: flags.programRoots)
-        .transform(program);
+        .transform(component);
     _hierarchy = null; // Hierarchy must be recomputed.
   }
 }
diff --git a/pkg/kernel/lib/target/vmreify.dart b/pkg/kernel/lib/target/vmreify.dart
index 65c1e66..681c760 100644
--- a/pkg/kernel/lib/target/vmreify.dart
+++ b/pkg/kernel/lib/target/vmreify.dart
@@ -3,10 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 library kernel.target.vmreify;
 
-import '../ast.dart' show Program;
+import '../ast.dart' show Component;
 import '../core_types.dart' show CoreTypes;
 import '../transformations/generic_types_reification.dart' as reify
-    show transformProgram;
+    show transformComponent;
 import 'targets.dart' show TargetFlags;
 import 'vmcc.dart' as vmcc_target;
 
@@ -27,18 +27,18 @@
   }
 
   @override
-  void performGlobalTransformations(CoreTypes coreTypes, Program program,
+  void performGlobalTransformations(CoreTypes coreTypes, Component component,
       {void logger(String msg)}) {
-    super.performGlobalTransformations(coreTypes, program);
+    super.performGlobalTransformations(coreTypes, component);
     // TODO(dmitryas) this transformation should be made modular
-    reify.transformProgram(coreTypes, program);
+    reify.transformComponent(coreTypes, component);
   }
 
   // Disable tree shaking for Generic Types Reification. There are some runtime
   // libraries that are required for the transformation and are shaken off,
-  // because they aren't invoked from the program being transformed prior to
+  // because they aren't invoked from the component being transformed prior to
   // the transformation.
   // TODO(dmitryas): remove this when the libraries are in dart:_internal
   @override
-  void performTreeShaking(CoreTypes coreTypes, Program program) {}
+  void performTreeShaking(CoreTypes coreTypes, Component component) {}
 }
diff --git a/pkg/kernel/lib/testing/mock_sdk_component.dart b/pkg/kernel/lib/testing/mock_sdk_component.dart
new file mode 100644
index 0000000..c85bdcf
--- /dev/null
+++ b/pkg/kernel/lib/testing/mock_sdk_component.dart
@@ -0,0 +1,68 @@
+// 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:kernel/ast.dart';
+
+/// Returns a [Component] object containing empty definitions of core SDK classes.
+Component createMockSdkComponent() {
+  var coreLib = new Library(Uri.parse('dart:core'), name: 'dart.core');
+  var asyncLib = new Library(Uri.parse('dart:async'), name: 'dart.async');
+  var internalLib =
+      new Library(Uri.parse('dart:_internal'), name: 'dart._internal');
+
+  Class addClass(Library lib, Class c) {
+    lib.addClass(c);
+    return c;
+  }
+
+  var objectClass = addClass(coreLib, new Class(name: 'Object'));
+  var objectType = objectClass.rawType;
+
+  TypeParameter typeParam(String name, [DartType bound]) {
+    return new TypeParameter(name, bound ?? objectType);
+  }
+
+  Class class_(String name,
+      {Supertype supertype,
+      List<TypeParameter> typeParameters,
+      List<Supertype> implementedTypes}) {
+    return new Class(
+        name: name,
+        supertype: supertype ?? objectClass.asThisSupertype,
+        typeParameters: typeParameters,
+        implementedTypes: implementedTypes);
+  }
+
+  addClass(coreLib, class_('Null'));
+  addClass(coreLib, class_('bool'));
+  var num = addClass(coreLib, class_('num'));
+  addClass(coreLib, class_('String'));
+  var iterable =
+      addClass(coreLib, class_('Iterable', typeParameters: [typeParam('T')]));
+  {
+    var T = typeParam('T');
+    addClass(
+        coreLib,
+        class_('List', typeParameters: [
+          T
+        ], implementedTypes: [
+          new Supertype(iterable, [new TypeParameterType(T)])
+        ]));
+  }
+  addClass(
+      coreLib, class_('Map', typeParameters: [typeParam('K'), typeParam('V')]));
+  addClass(coreLib, class_('int', supertype: num.asThisSupertype));
+  addClass(coreLib, class_('double', supertype: num.asThisSupertype));
+  addClass(coreLib, class_('Iterator', typeParameters: [typeParam('T')]));
+  addClass(coreLib, class_('Symbol'));
+  addClass(coreLib, class_('Type'));
+  addClass(coreLib, class_('Function'));
+  addClass(coreLib, class_('Invocation'));
+  addClass(asyncLib, class_('Future', typeParameters: [typeParam('T')]));
+  addClass(asyncLib, class_('FutureOr', typeParameters: [typeParam('T')]));
+  addClass(asyncLib, class_('Stream', typeParameters: [typeParam('T')]));
+  addClass(internalLib, class_('Symbol'));
+
+  return new Component(libraries: [coreLib, asyncLib, internalLib]);
+}
diff --git a/pkg/kernel/lib/testing/mock_sdk_program.dart b/pkg/kernel/lib/testing/mock_sdk_program.dart
deleted file mode 100644
index 832114b..0000000
--- a/pkg/kernel/lib/testing/mock_sdk_program.dart
+++ /dev/null
@@ -1,68 +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:kernel/ast.dart';
-
-/// Returns a [Program] object containing empty definitions of core SDK classes.
-Program createMockSdkProgram() {
-  var coreLib = new Library(Uri.parse('dart:core'), name: 'dart.core');
-  var asyncLib = new Library(Uri.parse('dart:async'), name: 'dart.async');
-  var internalLib =
-      new Library(Uri.parse('dart:_internal'), name: 'dart._internal');
-
-  Class addClass(Library lib, Class c) {
-    lib.addClass(c);
-    return c;
-  }
-
-  var objectClass = addClass(coreLib, new Class(name: 'Object'));
-  var objectType = objectClass.rawType;
-
-  TypeParameter typeParam(String name, [DartType bound]) {
-    return new TypeParameter(name, bound ?? objectType);
-  }
-
-  Class class_(String name,
-      {Supertype supertype,
-      List<TypeParameter> typeParameters,
-      List<Supertype> implementedTypes}) {
-    return new Class(
-        name: name,
-        supertype: supertype ?? objectClass.asThisSupertype,
-        typeParameters: typeParameters,
-        implementedTypes: implementedTypes);
-  }
-
-  addClass(coreLib, class_('Null'));
-  addClass(coreLib, class_('bool'));
-  var num = addClass(coreLib, class_('num'));
-  addClass(coreLib, class_('String'));
-  var iterable =
-      addClass(coreLib, class_('Iterable', typeParameters: [typeParam('T')]));
-  {
-    var T = typeParam('T');
-    addClass(
-        coreLib,
-        class_('List', typeParameters: [
-          T
-        ], implementedTypes: [
-          new Supertype(iterable, [new TypeParameterType(T)])
-        ]));
-  }
-  addClass(
-      coreLib, class_('Map', typeParameters: [typeParam('K'), typeParam('V')]));
-  addClass(coreLib, class_('int', supertype: num.asThisSupertype));
-  addClass(coreLib, class_('double', supertype: num.asThisSupertype));
-  addClass(coreLib, class_('Iterator', typeParameters: [typeParam('T')]));
-  addClass(coreLib, class_('Symbol'));
-  addClass(coreLib, class_('Type'));
-  addClass(coreLib, class_('Function'));
-  addClass(coreLib, class_('Invocation'));
-  addClass(asyncLib, class_('Future', typeParameters: [typeParam('T')]));
-  addClass(asyncLib, class_('FutureOr', typeParameters: [typeParam('T')]));
-  addClass(asyncLib, class_('Stream', typeParameters: [typeParam('T')]));
-  addClass(internalLib, class_('Symbol'));
-
-  return new Program(libraries: [coreLib, asyncLib, internalLib]);
-}
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 0db4862..fcf52cf 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -131,9 +131,10 @@
   return '$buffer';
 }
 
-String programToString(Program node) {
+String componentToString(Component node) {
   StringBuffer buffer = new StringBuffer();
-  new Printer(buffer, syntheticNames: new NameSystem()).writeProgramFile(node);
+  new Printer(buffer, syntheticNames: new NameSystem())
+      .writeComponentFile(node);
   return '$buffer';
 }
 
@@ -395,21 +396,21 @@
 
     endLine();
     var inner =
-        new Printer._inner(this, imports, library.enclosingProgram?.metadata);
+        new Printer._inner(this, imports, library.enclosingComponent?.metadata);
     library.typedefs.forEach(inner.writeNode);
     library.classes.forEach(inner.writeNode);
     library.fields.forEach(inner.writeNode);
     library.procedures.forEach(inner.writeNode);
   }
 
-  void writeProgramFile(Program program) {
-    ImportTable imports = new ProgramImportTable(program);
-    var inner = new Printer._inner(this, imports, program.metadata);
+  void writeComponentFile(Component component) {
+    ImportTable imports = new ComponentImportTable(component);
+    var inner = new Printer._inner(this, imports, component.metadata);
     writeWord('main');
     writeSpaced('=');
-    inner.writeMemberReferenceFromReference(program.mainMethodName);
+    inner.writeMemberReferenceFromReference(component.mainMethodName);
     endLine(';');
-    for (var library in program.libraries) {
+    for (var library in component.libraries) {
       if (library.isExternal) {
         if (!showExternal) {
           continue;
@@ -1447,6 +1448,21 @@
     endLine('}');
   }
 
+  visitAssertBlock(AssertBlock node) {
+    writeIndentation();
+    writeSpaced('assert');
+    if (node.statements.isEmpty) {
+      endLine('{}');
+      return;
+    }
+    endLine('{');
+    ++indentation;
+    node.statements.forEach(writeNode);
+    --indentation;
+    writeIndentation();
+    endLine('}');
+  }
+
   visitEmptyStatement(EmptyStatement node) {
     writeIndentation();
     endLine(';');
diff --git a/pkg/kernel/lib/transformations/argument_extraction.dart b/pkg/kernel/lib/transformations/argument_extraction.dart
index 699f87e..98af6a5 100644
--- a/pkg/kernel/lib/transformations/argument_extraction.dart
+++ b/pkg/kernel/lib/transformations/argument_extraction.dart
@@ -11,15 +11,15 @@
         Initializer,
         Library,
         LocalInitializer,
-        Program,
+        Component,
         VariableDeclaration,
         VariableGet;
 import '../core_types.dart' show CoreTypes;
 import '../visitor.dart' show Transformer;
 
-Program transformProgram(CoreTypes coreTypes, Program program) {
-  new ArgumentExtractionForTesting().visitProgram(program);
-  return program;
+Component transformComponent(CoreTypes coreTypes, Component component) {
+  new ArgumentExtractionForTesting().visitComponent(component);
+  return component;
 }
 
 void transformLibraries(CoreTypes coreTypes, List<Library> libraries) {
diff --git a/pkg/kernel/lib/transformations/closure_conversion.dart b/pkg/kernel/lib/transformations/closure_conversion.dart
index 8080997..d1471aa 100644
--- a/pkg/kernel/lib/transformations/closure_conversion.dart
+++ b/pkg/kernel/lib/transformations/closure_conversion.dart
@@ -4,7 +4,7 @@
 
 library kernel.transformations.closure_conversion;
 
-import '../ast.dart' show Program, Library;
+import '../ast.dart' show Component, Library;
 
 import '../core_types.dart' show CoreTypes;
 
@@ -14,13 +14,13 @@
 
 import 'closure/invalidate_closures.dart';
 
-Program transformProgram(CoreTypes coreTypes, Program program) {
+Component transformComponent(CoreTypes coreTypes, Component component) {
   var info = new ClosureInfo();
-  info.visitProgram(program);
+  info.visitComponent(component);
 
   var convert = new ClosureConverter(coreTypes, info);
-  program = convert.visitProgram(program);
-  return new InvalidateClosures().visitProgram(program);
+  component = convert.visitComponent(component);
+  return new InvalidateClosures().visitComponent(component);
 }
 
 void transformLibraries(CoreTypes coreTypes, List<Library> libraries) {
diff --git a/pkg/kernel/lib/transformations/constants.dart b/pkg/kernel/lib/transformations/constants.dart
index 9cb7a4d..84ae345 100644
--- a/pkg/kernel/lib/transformations/constants.dart
+++ b/pkg/kernel/lib/transformations/constants.dart
@@ -26,23 +26,23 @@
 import '../class_hierarchy.dart';
 import 'treeshaker.dart' show findNativeName;
 
-Program transformProgram(Program program, ConstantsBackend backend,
+Component transformComponent(Component component, ConstantsBackend backend,
     {bool keepFields: false,
     bool strongMode: false,
     bool enableAsserts: false,
     CoreTypes coreTypes,
     ClassHierarchy hierarchy}) {
-  coreTypes ??= new CoreTypes(program);
-  hierarchy ??= new ClassHierarchy(program);
+  coreTypes ??= new CoreTypes(component);
+  hierarchy ??= new ClassHierarchy(component);
 
   final typeEnvironment =
       new TypeEnvironment(coreTypes, hierarchy, strongMode: strongMode);
 
-  transformLibraries(program.libraries, backend, coreTypes, typeEnvironment,
+  transformLibraries(component.libraries, backend, coreTypes, typeEnvironment,
       keepFields: keepFields,
       strongMode: strongMode,
       enableAsserts: enableAsserts);
-  return program;
+  return component;
 }
 
 void transformLibraries(List<Library> libraries, ConstantsBackend backend,
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index d6ff80f..ae9076f 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -21,10 +21,11 @@
   }
 }
 
-Program transformProgram(CoreTypes coreTypes, Program program, bool syncAsync) {
+Component transformComponent(
+    CoreTypes coreTypes, Component component, bool syncAsync) {
   var helper = new HelperNodes.fromCoreTypes(coreTypes);
   var rewriter = new RecursiveContinuationRewriter(helper, syncAsync);
-  return rewriter.rewriteProgram(program);
+  return rewriter.rewriteComponent(component);
 }
 
 Procedure transformProcedure(
@@ -48,7 +49,7 @@
 
   RecursiveContinuationRewriter(this.helper, this.syncAsync);
 
-  Program rewriteProgram(Program node) {
+  Component rewriteComponent(Component node) {
     return node.accept(this);
   }
 
@@ -394,8 +395,73 @@
     return null;
   }
 
+  TreeNode visitAssertBlock(AssertBlock stmt) {
+    var saved = statements;
+    statements = <Statement>[];
+    for (var statement in stmt.statements) {
+      statement.accept(this);
+    }
+    saved.add(new Block(statements));
+    statements = saved;
+    return null;
+  }
+
   TreeNode visitAssertStatement(AssertStatement stmt) {
-    // TODO!
+    var condEffects = <Statement>[];
+    var cond = expressionRewriter.rewrite(stmt.condition, condEffects);
+    if (stmt.message == null) {
+      stmt.condition = cond..parent = stmt;
+      // If the translation of the condition produced a non-empty list of
+      // statements, ensure they are guarded by whether asserts are enabled.
+      statements.add(
+          condEffects.isEmpty ? stmt : new AssertBlock(condEffects..add(stmt)));
+      return null;
+    }
+
+    // The translation depends on the translation of the message, by cases.
+    Statement result;
+    var msgEffects = <Statement>[];
+    stmt.message = expressionRewriter.rewrite(stmt.message, msgEffects)
+      ..parent = stmt;
+    if (condEffects.isEmpty) {
+      if (msgEffects.isEmpty) {
+        // The condition rewrote to ([], C) and the message rewrote to ([], M).
+        // The result is
+        //
+        // assert(C, M)
+        stmt.condition = cond..parent = stmt;
+        result = stmt;
+      } else {
+        // The condition rewrote to ([], C) and the message rewrote to (S*, M)
+        // where S* is non-empty.  The result is
+        //
+        // assert { if (C) {} else { S*; assert(false, M); }}
+        stmt.condition = new BoolLiteral(false)..parent = stmt;
+        result = new AssertBlock([
+          new IfStatement(
+              cond, new EmptyStatement(), new Block(msgEffects..add(stmt)))
+        ]);
+      }
+    } else {
+      if (msgEffects.isEmpty) {
+        // The condition rewrote to (S*, C) where S* is non-empty and the
+        // message rewrote to ([], M).  The result is
+        //
+        // assert { S*; assert(C, M); }
+        stmt.condition = cond..parent = stmt;
+        condEffects.add(stmt);
+      } else {
+        // The condition rewrote to (S0*, C) and the message rewrote to (S1*, M)
+        // where both S0* and S1* are non-empty.  The result is
+        //
+        // assert { S0*; if (C) {} else { S1*; assert(false, M); }}
+        stmt.condition = new BoolLiteral(false)..parent = stmt;
+        condEffects.add(new IfStatement(
+            cond, new EmptyStatement(), new Block(msgEffects..add(stmt))));
+      }
+      result = new AssertBlock(condEffects);
+    }
+    statements.add(result);
     return null;
   }
 
diff --git a/pkg/kernel/lib/transformations/coq.dart b/pkg/kernel/lib/transformations/coq.dart
index ae9cb72..f668737 100644
--- a/pkg/kernel/lib/transformations/coq.dart
+++ b/pkg/kernel/lib/transformations/coq.dart
@@ -512,8 +512,8 @@
       "Definition ast_store_validity (ast : ast_store) : Prop := \n$clause\n.");
 }
 
-Program transformProgram(CoreTypes coreTypes, Program program) {
-  for (Library lib in program.libraries) {
+Component transformComponent(CoreTypes coreTypes, Component component) {
+  for (Library lib in component.libraries) {
     // TODO(30610): Ideally we'd output to the file in the coq annotation on the
     // library name, but currently fasta throws away annotations on libraries.
     // Instead, we just special case "kernel.ast" and output to stdout.
@@ -524,5 +524,5 @@
     outputCoqImports();
     outputCoqSyntax(info);
   }
-  return program;
+  return component;
 }
diff --git a/pkg/kernel/lib/transformations/empty.dart b/pkg/kernel/lib/transformations/empty.dart
index 263858f..5a264dd7 100644
--- a/pkg/kernel/lib/transformations/empty.dart
+++ b/pkg/kernel/lib/transformations/empty.dart
@@ -8,9 +8,9 @@
 import '../kernel.dart';
 import '../visitor.dart';
 
-Program transformProgram(Program program) {
-  new EmptyTransformer().visitProgram(program);
-  return program;
+Component transformComponent(Component component) {
+  new EmptyTransformer().visitComponent(component);
+  return component;
 }
 
 class EmptyTransformer extends Transformer {}
diff --git a/pkg/kernel/lib/transformations/generic_types_reification.dart b/pkg/kernel/lib/transformations/generic_types_reification.dart
index 8bdf691..d79ab68 100644
--- a/pkg/kernel/lib/transformations/generic_types_reification.dart
+++ b/pkg/kernel/lib/transformations/generic_types_reification.dart
@@ -4,11 +4,11 @@
 
 library kernel.transformation.generic_types_reification;
 
-import '../ast.dart' show Program;
+import '../ast.dart' show Component;
 import '../core_types.dart' show CoreTypes;
 import '../transformations/reify/reify_transformer.dart' as reify
-    show transformProgram;
+    show transformComponent;
 
-Program transformProgram(CoreTypes coreTypes, Program program) {
-  return reify.transformProgram(coreTypes, program);
+Component transformComponent(CoreTypes coreTypes, Component component) {
+  return reify.transformComponent(coreTypes, component);
 }
diff --git a/pkg/kernel/lib/transformations/method_call.dart b/pkg/kernel/lib/transformations/method_call.dart
index 9590539..b269aff 100644
--- a/pkg/kernel/lib/transformations/method_call.dart
+++ b/pkg/kernel/lib/transformations/method_call.dart
@@ -53,11 +53,12 @@
 ///   var b = new B();
 ///   b.foo(499, named1: 88);
 /// }
-Program transformProgram(
-    CoreTypes coreTypes, ClassHierarchy hierarchy, Program program,
+Component transformComponent(
+    CoreTypes coreTypes, ClassHierarchy hierarchy, Component component,
     [debug = false]) {
-  new MethodCallTransformer(coreTypes, hierarchy, debug).visitProgram(program);
-  return program;
+  new MethodCallTransformer(coreTypes, hierarchy, debug)
+      .visitComponent(component);
+  return component;
 }
 
 class MethodCallTransformer extends Transformer {
@@ -115,7 +116,7 @@
   MethodCallTransformer(this.coreTypes, this.hierarchy, this._debug);
 
   @override
-  TreeNode visitProgram(Program node) {
+  TreeNode visitComponent(Component node) {
     // First move body of all procedures that takes optional positional or named
     // parameters and record which non-static procedure names have optional
     // positional arguments.
@@ -1256,9 +1257,9 @@
 
   // Below methods used to add debug prints etc
 
-  Library _getDartCoreLibrary(Program program) {
-    if (program == null) return null;
-    return program.libraries.firstWhere((lib) =>
+  Library _getDartCoreLibrary(Component component) {
+    if (component == null) return null;
+    return component.libraries.firstWhere((lib) =>
         lib.importUri.scheme == 'dart' && lib.importUri.path == 'core');
   }
 
@@ -1277,8 +1278,8 @@
   }
 
   Expression _getPrintExpression(String msg, TreeNode treeNode) {
-    TreeNode program = treeNode;
-    while (program is! Program) program = program.parent;
+    TreeNode component = treeNode;
+    while (component is! Component) component = component.parent;
     var finalMsg = msg;
     if (treeNode is Member) {
       finalMsg += " [ ${treeNode.name.name} ]";
@@ -1291,9 +1292,9 @@
     }
 
     var stacktrace = new StaticGet(_getProcedureInClassInLib(
-        _getDartCoreLibrary(program), 'StackTrace', 'current'));
+        _getDartCoreLibrary(component), 'StackTrace', 'current'));
     var printStackTrace = new StaticInvocation(
-        _getProcedureInLib(_getDartCoreLibrary(program), 'print'),
+        _getProcedureInLib(_getDartCoreLibrary(component), 'print'),
         new Arguments([
           new StringConcatenation([
             new StringLiteral(finalMsg),
diff --git a/pkg/kernel/lib/transformations/reify/analysis/program_analysis.dart b/pkg/kernel/lib/transformations/reify/analysis/program_analysis.dart
index 12bf4ae..df259b6 100644
--- a/pkg/kernel/lib/transformations/reify/analysis/program_analysis.dart
+++ b/pkg/kernel/lib/transformations/reify/analysis/program_analysis.dart
@@ -98,9 +98,9 @@
 
 bool _analyzeAll(Library library) => true;
 
-ProgramKnowledge analyze(Program program,
+ProgramKnowledge analyze(Component component,
     {LibraryFilter analyzeLibrary: _analyzeAll}) {
   ProgramKnowledge knowledge = new ProgramKnowledge();
-  program.accept(new ProgramAnalysis(knowledge, analyzeLibrary));
+  component.accept(new ProgramAnalysis(knowledge, analyzeLibrary));
   return knowledge;
 }
diff --git a/pkg/kernel/lib/transformations/reify/reify_transformer.dart b/pkg/kernel/lib/transformations/reify/reify_transformer.dart
index 176709a..5a0f2a5 100644
--- a/pkg/kernel/lib/transformations/reify/reify_transformer.dart
+++ b/pkg/kernel/lib/transformations/reify/reify_transformer.dart
@@ -21,7 +21,7 @@
 
 import '../../core_types.dart' show CoreTypes;
 
-RuntimeLibrary findRuntimeTypeLibrary(Program p) {
+RuntimeLibrary findRuntimeTypeLibrary(Component p) {
   Library findLibraryEndingWith(String postfix) {
     Iterable<Library> candidates = p.libraries.where((Library l) {
       return l.importUri.toString().endsWith(postfix);
@@ -40,37 +40,37 @@
   return new RuntimeLibrary(types, declarations, interceptors);
 }
 
-Program transformProgramUsingLibraries(
-    CoreTypes coreTypes, Program program, RuntimeLibrary runtimeLibrary,
+Component transformComponentUsingLibraries(
+    CoreTypes coreTypes, Component component, RuntimeLibrary runtimeLibrary,
     [Library libraryToTransform]) {
   LibraryFilter filter = libraryToTransform != null
       ? (Library library) => library == libraryToTransform
       : (_) => true;
-  ProgramKnowledge knowledge = analyze(program, analyzeLibrary: filter);
-  Library mainLibrary = program.mainMethod.parent;
+  ProgramKnowledge knowledge = analyze(component, analyzeLibrary: filter);
+  Library mainLibrary = component.mainMethod.parent;
   RuntimeTypeSupportBuilder builder =
       new RuntimeTypeSupportBuilder(runtimeLibrary, coreTypes, mainLibrary);
   ReifyVisitor transformer =
       new ReifyVisitor(runtimeLibrary, builder, knowledge, libraryToTransform);
-  // Transform the main program.
-  program = program.accept(transformer);
+  // Transform the main component.
+  component = component.accept(transformer);
   if (!filter(runtimeLibrary.interceptorsLibrary)) {
     // We need to transform the interceptor function in any case to make sure
     // that the type literals in the interceptor function are rewritten.
     runtimeLibrary.interceptorFunction.accept(transformer);
   }
   builder.createDeclarations();
-  program = program.accept(new Erasure(transformer));
+  component = component.accept(new Erasure(transformer));
   // TODO(karlklose): skip checks in debug mode
-  verifyProgram(program);
-  return program;
+  verifyComponent(component);
+  return component;
 }
 
-Program transformProgram(CoreTypes coreTypes, Program program) {
-  RuntimeLibrary runtimeLibrary = findRuntimeTypeLibrary(program);
-  Library mainLibrary = program.mainMethod.enclosingLibrary;
-  return transformProgramUsingLibraries(
-      coreTypes, program, runtimeLibrary, mainLibrary);
+Component transformComponent(CoreTypes coreTypes, Component component) {
+  RuntimeLibrary runtimeLibrary = findRuntimeTypeLibrary(component);
+  Library mainLibrary = component.mainMethod.enclosingLibrary;
+  return transformComponentUsingLibraries(
+      coreTypes, component, runtimeLibrary, mainLibrary);
 }
 
 main(List<String> arguments) async {
@@ -80,13 +80,13 @@
     output = Uri.base.resolve(arguments[1]);
   }
   Uri uri = Uri.base.resolve(path);
-  Program program = loadProgramFromBinary(uri.toFilePath());
-  CoreTypes coreTypes = new CoreTypes(program);
+  Component component = loadComponentFromBinary(uri.toFilePath());
+  CoreTypes coreTypes = new CoreTypes(component);
 
-  RuntimeLibrary runtimeLibrary = findRuntimeTypeLibrary(program);
-  Library mainLibrary = program.mainMethod.enclosingLibrary;
-  program = transformProgramUsingLibraries(
-      coreTypes, program, runtimeLibrary, mainLibrary);
+  RuntimeLibrary runtimeLibrary = findRuntimeTypeLibrary(component);
+  Library mainLibrary = component.mainMethod.enclosingLibrary;
+  component = transformComponentUsingLibraries(
+      coreTypes, component, runtimeLibrary, mainLibrary);
 
   if (output == null) {
     // Print result
@@ -97,13 +97,13 @@
   } else {
     IOSink sink = new File.fromUri(output).openWrite();
     try {
-      new BinaryPrinter(sink).writeProgramFile(program);
+      new BinaryPrinter(sink).writeComponentFile(component);
     } finally {
       await sink.close();
     }
     try {
       // Check that we can read the binary file.
-      loadProgramFromBinary(output.toFilePath());
+      loadComponentFromBinary(output.toFilePath());
     } catch (e) {
       print("Error when attempting to read $output.");
       rethrow;
diff --git a/pkg/kernel/lib/transformations/sanitize_for_vm.dart b/pkg/kernel/lib/transformations/sanitize_for_vm.dart
index 54d7e7d..afe812d 100644
--- a/pkg/kernel/lib/transformations/sanitize_for_vm.dart
+++ b/pkg/kernel/lib/transformations/sanitize_for_vm.dart
@@ -9,8 +9,8 @@
 ///
 /// VM-specific constraints that don't fit in anywhere else can be put here.
 class SanitizeForVM {
-  void transform(Program program) {
-    for (var library in program.libraries) {
+  void transform(Component component) {
+    for (var library in component.libraries) {
       for (var class_ in library.classes) {
         if (class_.constructors.isEmpty && class_.procedures.isEmpty) {
           class_.addMember(new Constructor(
diff --git a/pkg/kernel/lib/transformations/setup_builtin_library.dart b/pkg/kernel/lib/transformations/setup_builtin_library.dart
index 3fe2f14..07adcb4 100644
--- a/pkg/kernel/lib/transformations/setup_builtin_library.dart
+++ b/pkg/kernel/lib/transformations/setup_builtin_library.dart
@@ -9,12 +9,12 @@
 // The DartVM has a special `dart:_builtin` library which exposes a
 // `_getMainClosure()` method.  We need to change this method to return a
 // closure of `main()`.
-Program transformProgram(Program program,
+Component transformComponent(Component component,
     {String libraryUri: 'dart:_builtin'}) {
-  Procedure mainMethod = program.mainMethod;
+  Procedure mainMethod = component.mainMethod;
 
   Library builtinLibrary;
-  for (Library library in program.libraries) {
+  for (Library library in component.libraries) {
     if (library.importUri.toString() == libraryUri) {
       builtinLibrary = library;
       break;
@@ -46,5 +46,5 @@
     getMainClosure.body = null;
   }
 
-  return program;
+  return component;
 }
diff --git a/pkg/kernel/lib/transformations/treeshaker.dart b/pkg/kernel/lib/transformations/treeshaker.dart
index 6d482b0..3fd7046 100644
--- a/pkg/kernel/lib/transformations/treeshaker.dart
+++ b/pkg/kernel/lib/transformations/treeshaker.dart
@@ -10,13 +10,13 @@
 import '../type_environment.dart';
 import '../library_index.dart';
 
-Program transformProgram(
-    CoreTypes coreTypes, ClassHierarchy hierarchy, Program program,
+Component transformComponent(
+    CoreTypes coreTypes, ClassHierarchy hierarchy, Component component,
     {List<ProgramRoot> programRoots, bool strongMode: false}) {
-  new TreeShaker(coreTypes, hierarchy, program,
+  new TreeShaker(coreTypes, hierarchy, component,
           programRoots: programRoots, strongMode: strongMode)
-      .transform(program);
-  return program;
+      .transform(component);
+  return component;
 }
 
 enum ProgramRootKind {
@@ -94,7 +94,7 @@
 class TreeShaker {
   final CoreTypes coreTypes;
   final ClosedWorldClassHierarchy hierarchy;
-  final Program program;
+  final Component component;
   final bool strongMode;
   final List<ProgramRoot> programRoots;
 
@@ -175,9 +175,10 @@
   /// the mirrors library.
   bool get forceShaking => programRoots != null && programRoots.isNotEmpty;
 
-  TreeShaker(CoreTypes coreTypes, ClassHierarchy hierarchy, Program program,
+  TreeShaker(CoreTypes coreTypes, ClassHierarchy hierarchy, Component component,
       {bool strongMode: false, List<ProgramRoot> programRoots})
-      : this._internal(coreTypes, hierarchy, program, strongMode, programRoots);
+      : this._internal(
+            coreTypes, hierarchy, component, strongMode, programRoots);
 
   bool isMemberBodyUsed(Member member) {
     return _usedMembers.containsKey(member);
@@ -216,15 +217,15 @@
     return _classRetention[index];
   }
 
-  /// Applies the tree shaking results to the program.
+  /// Applies the tree shaking results to the component.
   ///
   /// This removes unused classes, members, and hierarchy data.
-  void transform(Program program) {
+  void transform(Component component) {
     if (isUsingMirrors) return; // Give up if using mirrors.
-    new _TreeShakingTransformer(this).transform(program);
+    new _TreeShakingTransformer(this).transform(component);
   }
 
-  TreeShaker._internal(this.coreTypes, this.hierarchy, this.program,
+  TreeShaker._internal(this.coreTypes, this.hierarchy, this.component,
       this.strongMode, this.programRoots)
       : this._dispatchedNames = new List<Set<Name>>(hierarchy.classes.length),
         this._usedMembersWithHost =
@@ -246,19 +247,20 @@
   }
 
   void _build() {
-    if (program.mainMethod == null) {
-      throw 'Cannot perform tree shaking on a program without a main method';
+    if (component.mainMethod == null) {
+      throw 'Cannot perform tree shaking on a component without a main method';
     }
-    if (program.mainMethod.function.positionalParameters.length > 0) {
+    if (component.mainMethod.function.positionalParameters.length > 0) {
       // The main method takes a List<String> as argument.
       _addInstantiatedExternalSubclass(coreTypes.listClass);
       _addInstantiatedExternalSubclass(coreTypes.stringClass);
     }
     _addDispatchedName(coreTypes.objectClass, new Name('noSuchMethod'));
     _addPervasiveUses();
-    _addUsedMember(null, program.mainMethod);
+    _addUsedMember(null, component.mainMethod);
     if (programRoots != null) {
-      var table = new LibraryIndex(program, programRoots.map((r) => r.library));
+      var table =
+          new LibraryIndex(component, programRoots.map((r) => r.library));
       for (var root in programRoots) {
         _addUsedRoot(root, table);
       }
@@ -1030,7 +1032,7 @@
     return isUsed ? target : null;
   }
 
-  void transform(Program program) {
+  void transform(Component component) {
     for (Expression node in shaker._typedCalls) {
       // We should not leave dangling references, so if the target of a typed
       // call has been removed, we must remove the reference.  The receiver of
@@ -1044,7 +1046,7 @@
         node.interfaceTarget = _translateInterfaceTarget(node.interfaceTarget);
       }
     }
-    for (var library in program.libraries) {
+    for (var library in component.libraries) {
       if (!shaker.forceShaking && library.importUri.scheme == 'dart') {
         // The backend expects certain things to be present in the core
         // libraries, so we currently don't shake off anything there.
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index 7b73df2..39412ae 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -25,8 +25,8 @@
         new TypeEnvironment(coreTypes, hierarchy, strongMode: strongMode);
   }
 
-  void checkProgram(Program program) {
-    for (var library in program.libraries) {
+  void checkComponent(Component component) {
+    for (var library in component.libraries) {
       if (ignoreSdk && library.importUri.scheme == 'dart') continue;
       for (var class_ in library.classes) {
         hierarchy.forEachOverridePair(class_,
@@ -36,7 +36,7 @@
       }
     }
     var visitor = new TypeCheckingVisitor(this, environment);
-    for (var library in program.libraries) {
+    for (var library in component.libraries) {
       if (ignoreSdk && library.importUri.scheme == 'dart') continue;
       for (var class_ in library.classes) {
         environment.thisType = class_.thisType;
@@ -823,6 +823,11 @@
   }
 
   @override
+  visitAssertBlock(AssertBlock node) {
+    node.statements.forEach(visitStatement);
+  }
+
+  @override
   visitBreakStatement(BreakStatement node) {}
 
   @override
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index fbbfb81..4239b87 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -6,8 +6,8 @@
 import 'ast.dart';
 import 'transformations/flags.dart';
 
-void verifyProgram(Program program) {
-  VerifyingVisitor.check(program);
+void verifyComponent(Component component) {
+  VerifyingVisitor.check(component);
 }
 
 class VerificationError {
@@ -40,7 +40,7 @@
 
 enum TypedefState { Done, BeingChecked }
 
-/// Checks that a kernel program is well-formed.
+/// Checks that a kernel component is well-formed.
 ///
 /// This does not include any kind of type checking.
 class VerifyingVisitor extends RecursiveVisitor {
@@ -67,8 +67,8 @@
 
   TreeNode get context => currentMember ?? currentClass;
 
-  static void check(Program program) {
-    program.accept(new VerifyingVisitor());
+  static void check(Component component) {
+    component.accept(new VerifyingVisitor());
   }
 
   defaultTreeNode(TreeNode node) {
@@ -165,9 +165,9 @@
     }
   }
 
-  visitProgram(Program program) {
+  visitComponent(Component component) {
     try {
-      for (var library in program.libraries) {
+      for (var library in component.libraries) {
         for (var class_ in library.classes) {
           if (!classes.add(class_)) {
             problem(class_, "Class '$class_' declared more than once.");
@@ -183,9 +183,9 @@
           class_.members.forEach(declareMember);
         }
       }
-      visitChildren(program);
+      visitChildren(component);
     } finally {
-      for (var library in program.libraries) {
+      for (var library in component.libraries) {
         library.members.forEach(undeclareMember);
         for (var class_ in library.classes) {
           class_.members.forEach(undeclareMember);
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index 5890d5f..fa6337c 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -75,6 +75,7 @@
   R visitExpressionStatement(ExpressionStatement node) =>
       defaultStatement(node);
   R visitBlock(Block node) => defaultStatement(node);
+  R visitAssertBlock(AssertBlock node) => defaultStatement(node);
   R visitEmptyStatement(EmptyStatement node) => defaultStatement(node);
   R visitAssertStatement(AssertStatement node) => defaultStatement(node);
   R visitLabeledStatement(LabeledStatement node) => defaultStatement(node);
@@ -196,6 +197,7 @@
   R visitExpressionStatement(ExpressionStatement node) =>
       defaultStatement(node);
   R visitBlock(Block node) => defaultStatement(node);
+  R visitAssertBlock(AssertBlock node) => defaultStatement(node);
   R visitEmptyStatement(EmptyStatement node) => defaultStatement(node);
   R visitAssertStatement(AssertStatement node) => defaultStatement(node);
   R visitLabeledStatement(LabeledStatement node) => defaultStatement(node);
@@ -253,7 +255,7 @@
   R visitSwitchCase(SwitchCase node) => defaultTreeNode(node);
   R visitCatch(Catch node) => defaultTreeNode(node);
   R visitMapEntry(MapEntry node) => defaultTreeNode(node);
-  R visitProgram(Program node) => defaultTreeNode(node);
+  R visitComponent(Component node) => defaultTreeNode(node);
 }
 
 class DartTypeVisitor<R> {
@@ -514,6 +516,7 @@
   R visitExpressionStatement(ExpressionStatement node, T arg) =>
       defaultStatement(node, arg);
   R visitBlock(Block node, T arg) => defaultStatement(node, arg);
+  R visitAssertBlock(AssertBlock node, T arg) => defaultStatement(node, arg);
   R visitEmptyStatement(EmptyStatement node, T arg) =>
       defaultStatement(node, arg);
   R visitAssertStatement(AssertStatement node, T arg) =>
diff --git a/pkg/kernel/test/ast_membench.dart b/pkg/kernel/test/ast_membench.dart
index 47eda46..dc50ccc 100644
--- a/pkg/kernel/test/ast_membench.dart
+++ b/pkg/kernel/test/ast_membench.dart
@@ -5,7 +5,7 @@
 import 'package:kernel/kernel.dart';
 import 'dart:io';
 
-/// Builds N copies of the AST for the given program.
+/// Builds N copies of the AST for the given component.
 /// Pass --print-metrics to the Dart VM to measure the memory use.
 main(List<String> args) {
   if (args.length == 0) {
@@ -16,9 +16,9 @@
 
   const int defaultCopyCount = 10;
   int copyCount = args.length == 2 ? int.parse(args[1]) : defaultCopyCount;
-  List<Program> keepAlive = <Program>[];
+  List<Component> keepAlive = <Component>[];
   for (int i = 0; i < copyCount; ++i) {
-    keepAlive.add(loadProgramFromBinary(filename));
+    keepAlive.add(loadComponentFromBinary(filename));
   }
 
   print('$copyCount copies built');
@@ -26,8 +26,8 @@
   if (args.contains('-v')) {
     // Use of the list for something to avoid premature GC.
     int size = 0;
-    for (var program in keepAlive) {
-      size += program.libraries.length;
+    for (var component in keepAlive) {
+      size += component.libraries.length;
     }
     print(size);
   }
diff --git a/pkg/kernel/test/binary_bench.dart b/pkg/kernel/test/binary_bench.dart
index 92ac93f..18c7610 100644
--- a/pkg/kernel/test/binary_bench.dart
+++ b/pkg/kernel/test/binary_bench.dart
@@ -160,11 +160,11 @@
   return true;
 }
 
-Program _fromBinary(List<int> bytes, {eager: true}) {
-  var program = new Program();
+Component _fromBinary(List<int> bytes, {eager: true}) {
+  var component = new Component();
   new BinaryBuilder(bytes, filename: 'filename', disableLazyReading: eager)
-      .readSingleFileProgram(program);
-  return program;
+      .readSingleFileComponent(component);
+  return component;
 }
 
 class SimpleSink implements Sink<List<int>> {
@@ -179,6 +179,6 @@
   void close() {}
 }
 
-void _toBinary(Program p) {
-  new BinaryPrinter(new SimpleSink()).writeProgramFile(p);
+void _toBinary(Component p) {
+  new BinaryPrinter(new SimpleSink()).writeComponentFile(p);
 }
diff --git a/pkg/kernel/test/class_hierarchy_basic.dart b/pkg/kernel/test/class_hierarchy_basic.dart
index 8120505..1f69a0e 100644
--- a/pkg/kernel/test/class_hierarchy_basic.dart
+++ b/pkg/kernel/test/class_hierarchy_basic.dart
@@ -25,8 +25,8 @@
   final List<Class> classes = <Class>[];
   final Map<Class, int> classIndex = <Class, int>{};
 
-  BasicClassHierarchy(Program program) {
-    for (var library in program.libraries) {
+  BasicClassHierarchy(Component component) {
+    for (var library in component.libraries) {
       for (var classNode in library.classes) {
         buildSuperTypeSets(classNode);
         buildSuperTypeInstantiations(classNode);
diff --git a/pkg/kernel/test/class_hierarchy_bench.dart b/pkg/kernel/test/class_hierarchy_bench.dart
index 02d6b0c..37877d5 100644
--- a/pkg/kernel/test/class_hierarchy_bench.dart
+++ b/pkg/kernel/test/class_hierarchy_bench.dart
@@ -36,12 +36,12 @@
   }
   String filename = options.rest.single;
 
-  Program program = loadProgramFromBinary(filename);
+  Component component = loadComponentFromBinary(filename);
 
   ClassHierarchy buildHierarchy() {
     return options['basic']
-        ? new BasicClassHierarchy(program)
-        : new ClassHierarchy(program);
+        ? new BasicClassHierarchy(component)
+        : new ClassHierarchy(component);
   }
 
   var watch = new Stopwatch()..start();
diff --git a/pkg/kernel/test/class_hierarchy_membench.dart b/pkg/kernel/test/class_hierarchy_membench.dart
index dcec19a..cb0d031 100644
--- a/pkg/kernel/test/class_hierarchy_membench.dart
+++ b/pkg/kernel/test/class_hierarchy_membench.dart
@@ -22,7 +22,7 @@
 ${argParser.usage}
 """;
 
-/// Builds N copies of the class hierarchy for the given program.
+/// Builds N copies of the class hierarchy for the given component.
 /// Pass --print-metrics to the Dart VM to measure the memory use.
 main(List<String> args) {
   if (args.length == 0) {
@@ -36,14 +36,14 @@
   }
   String filename = options.rest.single;
 
-  Program program = loadProgramFromBinary(filename);
+  Component component = loadComponentFromBinary(filename);
 
   int copyCount = int.parse(options['count']);
 
   ClassHierarchy buildHierarchy() {
     return options['basic']
-        ? new BasicClassHierarchy(program)
-        : new ClassHierarchy(program);
+        ? new BasicClassHierarchy(component)
+        : new ClassHierarchy(component);
   }
 
   List<ClosedWorldClassHierarchy> keepAlive = <ClosedWorldClassHierarchy>[];
diff --git a/pkg/kernel/test/class_hierarchy_self_check.dart b/pkg/kernel/test/class_hierarchy_self_check.dart
index 1c12454..486db45 100644
--- a/pkg/kernel/test/class_hierarchy_self_check.dart
+++ b/pkg/kernel/test/class_hierarchy_self_check.dart
@@ -12,13 +12,13 @@
 
 main(List<String> args) {
   runSelfCheck(args, (String filename) {
-    testClassHierarchyOnProgram(loadProgramFromBinary(filename));
+    testClassHierarchyOnComponent(loadComponentFromBinary(filename));
   });
 }
 
-void testClassHierarchyOnProgram(Program program, {bool verbose: false}) {
-  BasicClassHierarchy basic = new BasicClassHierarchy(program);
-  ClosedWorldClassHierarchy classHierarchy = new ClassHierarchy(program);
+void testClassHierarchyOnComponent(Component component, {bool verbose: false}) {
+  BasicClassHierarchy basic = new BasicClassHierarchy(component);
+  ClosedWorldClassHierarchy classHierarchy = new ClassHierarchy(component);
   int total = classHierarchy.classes.length;
   int progress = 0;
   for (var class1 in classHierarchy.classes) {
diff --git a/pkg/kernel/test/class_hierarchy_test.dart b/pkg/kernel/test/class_hierarchy_test.dart
index ac89f98..b9b1dc6 100644
--- a/pkg/kernel/test/class_hierarchy_test.dart
+++ b/pkg/kernel/test/class_hierarchy_test.dart
@@ -5,7 +5,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/core_types.dart';
-import 'package:kernel/testing/mock_sdk_program.dart';
+import 'package:kernel/testing/mock_sdk_component.dart';
 import 'package:kernel/text/ast_to_text.dart';
 import 'package:kernel/type_algebra.dart';
 import 'package:test/test.dart';
@@ -19,8 +19,8 @@
 
 @reflectiveTest
 class ClosedWorldClassHierarchyTest extends _ClassHierarchyTest {
-  ClassHierarchy createClassHierarchy(Program program) {
-    return new ClassHierarchy(program);
+  ClassHierarchy createClassHierarchy(Component component) {
+    return new ClassHierarchy(component);
   }
 
   void test_applyChanges() {
@@ -142,7 +142,7 @@
 }
 
 abstract class _ClassHierarchyTest {
-  Program program;
+  Component component;
   CoreTypes coreTypes;
 
   /// The test library.
@@ -152,7 +152,7 @@
 
   /// Return the new or existing instance of [ClassHierarchy].
   ClassHierarchy get hierarchy {
-    return _hierarchy ??= createClassHierarchy(program);
+    return _hierarchy ??= createClassHierarchy(component);
   }
 
   Class get objectClass => coreTypes.objectClass;
@@ -199,7 +199,7 @@
         implementedTypes: implements_.map((c) => c.asThisSupertype).toList()));
   }
 
-  ClassHierarchy createClassHierarchy(Program program);
+  ClassHierarchy createClassHierarchy(Component component);
 
   Procedure newEmptyGetter(String name,
       {DartType returnType: const DynamicType(), bool isAbstract: false}) {
@@ -229,13 +229,13 @@
 
   void setUp() {
     // Start with mock SDK libraries.
-    program = createMockSdkProgram();
-    coreTypes = new CoreTypes(program);
+    component = createMockSdkComponent();
+    coreTypes = new CoreTypes(component);
 
     // Add the test library.
     library = new Library(Uri.parse('org-dartlang:///test.dart'), name: 'test');
-    library.parent = program;
-    program.libraries.add(library);
+    library.parent = component;
+    component.libraries.add(library);
   }
 
   /// 2. A non-abstract member is inherited from a superclass, and in the
diff --git a/pkg/kernel/test/class_hierarchy_test_disabled.dart b/pkg/kernel/test/class_hierarchy_test_disabled.dart
index 842f8a2..d1cd156 100644
--- a/pkg/kernel/test/class_hierarchy_test_disabled.dart
+++ b/pkg/kernel/test/class_hierarchy_test_disabled.dart
@@ -7,7 +7,7 @@
 
 main() {
   test('All-pairs class hierarchy tests on dart2js', () {
-    testClassHierarchyOnProgram(
-        loadProgramFromBinary('test/data/dart2js.dill'));
+    testClassHierarchyOnComponent(
+        loadComponentFromBinary('test/data/dart2js.dill'));
   });
 }
diff --git a/pkg/kernel/test/closures/suite.dart b/pkg/kernel/test/closures/suite.dart
index e29b394..a993f2e 100644
--- a/pkg/kernel/test/closures/suite.dart
+++ b/pkg/kernel/test/closures/suite.dart
@@ -13,7 +13,7 @@
 import 'package:testing/testing.dart'
     show Chain, ChainContext, Result, Step, runMe, StdioProcess;
 
-import 'package:kernel/ast.dart' show Program, Library;
+import 'package:kernel/ast.dart' show Component, Library;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -38,7 +38,7 @@
 
   final List<Step> steps;
 
-  Program platform;
+  Component platform;
 
   ClosureConversionContext(this.strongMode, bool updateExpectations)
       : steps = <Step>[
@@ -71,19 +71,19 @@
 }
 
 class ClosureConversion
-    extends Step<Program, Program, ClosureConversionContext> {
+    extends Step<Component, Component, ClosureConversionContext> {
   const ClosureConversion();
 
   String get name => "closure conversion";
 
-  Future<Result<Program>> run(
-      Program program, ClosureConversionContext testContext) async {
+  Future<Result<Component>> run(
+      Component component, ClosureConversionContext testContext) async {
     try {
-      CoreTypes coreTypes = new CoreTypes(program);
-      Library library = program.libraries
+      CoreTypes coreTypes = new CoreTypes(component);
+      Library library = component.libraries
           .firstWhere((Library library) => library.importUri.scheme != "dart");
       closure_conversion.transformLibraries(coreTypes, <Library>[library]);
-      return pass(program);
+      return pass(component);
     } catch (e, s) {
       return crash(e, s);
     }
diff --git a/pkg/kernel/test/closures_initializers/suite.dart b/pkg/kernel/test/closures_initializers/suite.dart
index c406c6e..d7176d4 100644
--- a/pkg/kernel/test/closures_initializers/suite.dart
+++ b/pkg/kernel/test/closures_initializers/suite.dart
@@ -11,7 +11,7 @@
 import 'package:testing/testing.dart'
     show Chain, ChainContext, Result, Step, runMe;
 
-import 'package:kernel/ast.dart' show Program, Library;
+import 'package:kernel/ast.dart' show Component, Library;
 
 import 'package:kernel/transformations/argument_extraction.dart'
     as argument_extraction;
@@ -74,19 +74,19 @@
 }
 
 class ArgumentExtraction
-    extends Step<Program, Program, ClosureConversionContext> {
+    extends Step<Component, Component, ClosureConversionContext> {
   const ArgumentExtraction();
 
   String get name => "argument extraction";
 
-  Future<Result<Program>> run(
-      Program program, ClosureConversionContext context) async {
+  Future<Result<Component>> run(
+      Component component, ClosureConversionContext context) async {
     try {
-      CoreTypes coreTypes = new CoreTypes(program);
-      Library library = program.libraries
+      CoreTypes coreTypes = new CoreTypes(component);
+      Library library = component.libraries
           .firstWhere((Library library) => library.importUri.scheme != "dart");
       argument_extraction.transformLibraries(coreTypes, <Library>[library]);
-      return pass(program);
+      return pass(component);
     } catch (e, s) {
       return crash(e, s);
     }
@@ -94,19 +94,19 @@
 }
 
 class ClosureConversion
-    extends Step<Program, Program, ClosureConversionContext> {
+    extends Step<Component, Component, ClosureConversionContext> {
   const ClosureConversion();
 
   String get name => "closure conversion";
 
-  Future<Result<Program>> run(
-      Program program, ClosureConversionContext testContext) async {
+  Future<Result<Component>> run(
+      Component component, ClosureConversionContext testContext) async {
     try {
-      CoreTypes coreTypes = new CoreTypes(program);
-      Library library = program.libraries
+      CoreTypes coreTypes = new CoreTypes(component);
+      Library library = component.libraries
           .firstWhere((Library library) => library.importUri.scheme != "dart");
       closure_conversion.transformLibraries(coreTypes, <Library>[library]);
-      return pass(program);
+      return pass(component);
     } catch (e, s) {
       return crash(e, s);
     }
diff --git a/pkg/kernel/test/frontend_bench.dart b/pkg/kernel/test/frontend_bench.dart
index 4e9ea38..78d01c2 100644
--- a/pkg/kernel/test/frontend_bench.dart
+++ b/pkg/kernel/test/frontend_bench.dart
@@ -48,14 +48,14 @@
   var uri = new Uri(scheme: 'file', path: new File(path).absolute.path);
   var packages =
       getPackagesDirectory(new Uri(scheme: 'file', path: packagePath));
-  Program repository = new Program();
+  Component repository = new Component();
 
   new DartLoader(
           repository,
           new DartOptions(
               strongMode: strongMode, sdk: sdk, packagePath: packagePath),
           packages)
-      .loadProgram(uri);
+      .loadComponent(uri);
 
   CacheEntry.recomputedCounts.forEach((key, value) {
     print('Recomputed $key $value times');
diff --git a/pkg/kernel/test/interpreter/suite.dart b/pkg/kernel/test/interpreter/suite.dart
index 33e0f6b..00a8e03 100644
--- a/pkg/kernel/test/interpreter/suite.dart
+++ b/pkg/kernel/test/interpreter/suite.dart
@@ -11,7 +11,7 @@
 import 'package:testing/testing.dart'
     show Chain, ChainContext, Result, Step, runMe;
 
-import 'package:kernel/ast.dart' show Program, Library;
+import 'package:kernel/ast.dart' show Component, Library;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -42,20 +42,20 @@
   }
 }
 
-class Interpret extends Step<Program, EvaluationLog, InterpreterContext> {
+class Interpret extends Step<Component, EvaluationLog, InterpreterContext> {
   const Interpret();
 
   String get name => "interpret";
 
-  Future<Result<EvaluationLog>> run(Program program, _) async {
-    Library library = program.libraries
+  Future<Result<EvaluationLog>> run(Component component, _) async {
+    Library library = component.libraries
         .firstWhere((Library library) => library.importUri.scheme != "dart");
     Uri uri = library.importUri;
 
     StringBuffer buffer = new StringBuffer();
     log.onRecord.listen((LogRecord rec) => buffer.write(rec.message));
     try {
-      new Interpreter(program).run();
+      new Interpreter(component).run();
     } catch (e, s) {
       return crash(e, s);
     }
diff --git a/pkg/kernel/test/metadata_test.dart b/pkg/kernel/test/metadata_test.dart
index ade939f..1fb9777 100644
--- a/pkg/kernel/test/metadata_test.dart
+++ b/pkg/kernel/test/metadata_test.dart
@@ -35,12 +35,12 @@
 
   void writeToBinary(Metadata metadata, BinarySink sink) {
     sink.writeNodeReference(metadata.parent);
-    sink.writeByteList(UTF8.encode(metadata.self));
+    sink.writeByteList(utf8.encode(metadata.self));
   }
 
   Metadata readFromBinary(BinarySource source) {
     final parent = source.readNodeReference();
-    final string = UTF8.decode(source.readByteList());
+    final string = utf8.decode(source.readByteList());
     return new Metadata(parent, string);
   }
 }
@@ -58,12 +58,12 @@
 }
 
 /// Visitor that assigns [Metadata] object created with [Metadata.forNode] to
-/// each supported node in the program.
+/// each supported node in the component.
 class Annotator extends RecursiveVisitor<Null> {
   final TestMetadataRepository repository;
 
-  Annotator(Program program)
-      : repository = program.metadata[TestMetadataRepository.kTag];
+  Annotator(Component component)
+      : repository = component.metadata[TestMetadataRepository.kTag];
 
   defaultTreeNode(TreeNode node) {
     super.defaultTreeNode(node);
@@ -72,19 +72,19 @@
     }
   }
 
-  static void annotate(Program p) {
+  static void annotate(Component p) {
     globalDebuggingNames = new NameSystem();
     p.accept(new Annotator(p));
   }
 }
 
-/// Visitor that checks that each supported node in the program has correct
+/// Visitor that checks that each supported node in the component has correct
 /// metadata.
 class Validator extends RecursiveVisitor<Null> {
   final TestMetadataRepository repository;
 
-  Validator(Program program)
-      : repository = program.metadata[TestMetadataRepository.kTag];
+  Validator(Component component)
+      : repository = component.metadata[TestMetadataRepository.kTag];
 
   defaultTreeNode(TreeNode node) {
     super.defaultTreeNode(node);
@@ -97,22 +97,22 @@
     }
   }
 
-  static void validate(Program p) {
+  static void validate(Component p) {
     globalDebuggingNames = new NameSystem();
     p.accept(new Validator(p));
   }
 }
 
-Program fromBinary(List<int> bytes) {
-  var program = new Program();
-  program.addMetadataRepository(new TestMetadataRepository());
-  new BinaryBuilderWithMetadata(bytes).readSingleFileProgram(program);
-  return program;
+Component fromBinary(List<int> bytes) {
+  var component = new Component();
+  component.addMetadataRepository(new TestMetadataRepository());
+  new BinaryBuilderWithMetadata(bytes).readSingleFileComponent(component);
+  return component;
 }
 
-List<int> toBinary(Program p) {
+List<int> toBinary(Component p) {
   final sink = new BytesBuilderSink();
-  new BinaryPrinter(sink).writeProgramFile(p);
+  new BinaryPrinter(sink).writeComponentFile(p);
   return sink.builder.takeBytes();
 }
 
@@ -123,12 +123,12 @@
     final List<int> platformBinary =
         await new File(platform.toFilePath()).readAsBytes();
 
-    final program = fromBinary(platformBinary);
-    Annotator.annotate(program);
-    Validator.validate(program);
+    final component = fromBinary(platformBinary);
+    Annotator.annotate(component);
+    Validator.validate(component);
 
-    final annotatedProgramBinary = toBinary(program);
-    final annotatedProgramFromBinary = fromBinary(annotatedProgramBinary);
-    Validator.validate(annotatedProgramFromBinary);
+    final annotatedComponentBinary = toBinary(component);
+    final annotatedComponentFromBinary = fromBinary(annotatedComponentBinary);
+    Validator.validate(annotatedComponentFromBinary);
   });
 }
diff --git a/pkg/kernel/test/reify/suite.dart b/pkg/kernel/test/reify/suite.dart
index b9a70a8..768fbdc 100644
--- a/pkg/kernel/test/reify/suite.dart
+++ b/pkg/kernel/test/reify/suite.dart
@@ -30,7 +30,7 @@
 import 'package:testing/testing.dart'
     show Chain, ChainContext, Result, StdioProcess, Step, runMe;
 
-import 'package:kernel/ast.dart' show Program;
+import 'package:kernel/ast.dart' show Component;
 
 import 'package:kernel/transformations/generic_types_reification.dart'
     as generic_types_reification;
@@ -96,11 +96,11 @@
 
   // Tree shaking needs to be disabled, because Generic Types Reification
   // transformation relies on certain runtime libraries to be present in
-  // the program that is being transformed. If the tree shaker is enabled,
+  // the component that is being transformed. If the tree shaker is enabled,
   // it just deletes everything from those libraries, because they aren't
-  // used in the program being transform prior to the transformation.
+  // used in the component being transformed prior to the transformation.
   @override
-  void performTreeShaking(CoreTypes coreTypes, Program program) {}
+  void performTreeShaking(CoreTypes coreTypes, Component component) {}
 
   // Adds the necessary runtime libraries.
   @override
@@ -111,16 +111,18 @@
   }
 }
 
-class GenericTypesReification extends Step<Program, Program, TestContext> {
+class GenericTypesReification extends Step<Component, Component, TestContext> {
   const GenericTypesReification();
 
   String get name => "generic types reification";
 
-  Future<Result<Program>> run(Program program, TestContext testContext) async {
+  Future<Result<Component>> run(
+      Component component, TestContext testContext) async {
     try {
-      CoreTypes coreTypes = new CoreTypes(program);
-      program = generic_types_reification.transformProgram(coreTypes, program);
-      return pass(program);
+      CoreTypes coreTypes = new CoreTypes(component);
+      component =
+          generic_types_reification.transformComponent(coreTypes, component);
+      return pass(component);
     } catch (e, s) {
       return crash(e, s);
     }
diff --git a/pkg/kernel/test/round_trip.dart b/pkg/kernel/test/round_trip.dart
index eb806ffd..8269b76 100644
--- a/pkg/kernel/test/round_trip.dart
+++ b/pkg/kernel/test/round_trip.dart
@@ -12,7 +12,7 @@
 const String usage = '''
 Usage: round_trip.dart FILE.dill
 
-Deserialize and serialize the given program and check that the resulting byte
+Deserialize and serialize the given component and check that the resulting byte
 sequence is identical to the original.
 ''';
 
@@ -25,9 +25,9 @@
 }
 
 void testRoundTrip(List<int> bytes) {
-  var program = new Program();
-  new BinaryBuilder(bytes).readSingleFileProgram(program);
-  new BinaryPrinterWithExpectedOutput(bytes).writeProgramFile(program);
+  var component = new Component();
+  new BinaryBuilder(bytes).readSingleFileComponent(component);
+  new BinaryPrinterWithExpectedOutput(bytes).writeComponentFile(component);
 }
 
 class DummyStreamConsumer extends StreamConsumer<List<int>> {
diff --git a/pkg/kernel/test/serialize_bench.dart b/pkg/kernel/test/serialize_bench.dart
index f19e1af..3957ddb 100644
--- a/pkg/kernel/test/serialize_bench.dart
+++ b/pkg/kernel/test/serialize_bench.dart
@@ -16,17 +16,17 @@
     print(usage);
     exit(1);
   }
-  Program program = loadProgramFromBinary(args[0]);
+  Component component = loadComponentFromBinary(args[0]);
 
   String destination = args[1];
   var watch = new Stopwatch()..start();
-  await writeProgramToBinary(program, destination);
+  await writeComponentToBinary(component, destination);
   int coldTime = watch.elapsedMilliseconds;
 
   watch.reset();
   int numTrials = 10;
   for (int i = 0; i < numTrials; ++i) {
-    await writeProgramToBinary(program, destination);
+    await writeComponentToBinary(component, destination);
   }
   double hotTime = watch.elapsedMilliseconds / numTrials;
 
diff --git a/pkg/kernel/test/treeshaker_bench.dart b/pkg/kernel/test/treeshaker_bench.dart
index 07f660e..5f6ef67 100644
--- a/pkg/kernel/test/treeshaker_bench.dart
+++ b/pkg/kernel/test/treeshaker_bench.dart
@@ -45,20 +45,20 @@
   String filename = options.rest.single;
   bool strongMode = options['strong'];
 
-  Program program = loadProgramFromBinary(filename);
+  Component component = loadComponentFromBinary(filename);
 
   ClassHierarchy buildClassHierarchy() {
     return options['basic']
-        ? new BasicClassHierarchy(program)
-        : new ClassHierarchy(program);
+        ? new BasicClassHierarchy(component)
+        : new ClassHierarchy(component);
   }
 
-  CoreTypes coreTypes = new CoreTypes(program);
+  CoreTypes coreTypes = new CoreTypes(component);
 
   var watch = new Stopwatch()..start();
   ClassHierarchy sharedClassHierarchy = buildClassHierarchy();
   int coldHierarchyTime = watch.elapsedMicroseconds;
-  var shaker = new TreeShaker(coreTypes, sharedClassHierarchy, program,
+  var shaker = new TreeShaker(coreTypes, sharedClassHierarchy, component,
       strongMode: strongMode);
   if (options['diagnose']) {
     print(shaker.getDiagnosticString());
@@ -80,7 +80,7 @@
     watch.reset();
     var hierarchy = getClassHierarchy();
     hotHierarchyTime += watch.elapsedMicroseconds;
-    new TreeShaker(coreTypes, hierarchy, program, strongMode: strongMode);
+    new TreeShaker(coreTypes, hierarchy, component, strongMode: strongMode);
     hotTreeShakingTime += watch.elapsedMicroseconds;
   }
   hotHierarchyTime ~/= numberOfTrials;
diff --git a/pkg/kernel/test/treeshaker_check.dart b/pkg/kernel/test/treeshaker_check.dart
index 4d40d3d..9597141 100644
--- a/pkg/kernel/test/treeshaker_check.dart
+++ b/pkg/kernel/test/treeshaker_check.dart
@@ -21,12 +21,12 @@
     print(usage);
     exit(1);
   }
-  var program = loadProgramFromBinary(args[0]);
-  var coreTypes = new CoreTypes(program);
-  var hierarchy = new ClassHierarchy(program);
-  var shaker = new TreeShaker(coreTypes, hierarchy, program);
-  shaker.transform(program);
-  new TreeShakingSanityCheck(shaker).visit(program);
+  var component = loadComponentFromBinary(args[0]);
+  var coreTypes = new CoreTypes(component);
+  var hierarchy = new ClassHierarchy(component);
+  var shaker = new TreeShaker(coreTypes, hierarchy, component);
+  shaker.transform(component);
+  new TreeShakingSanityCheck(shaker).visit(component);
 }
 
 class TreeShakingSanityCheck extends RecursiveVisitor {
diff --git a/pkg/kernel/test/treeshaker_dump.dart b/pkg/kernel/test/treeshaker_dump.dart
index b373fbf..8e56d71 100644
--- a/pkg/kernel/test/treeshaker_dump.dart
+++ b/pkg/kernel/test/treeshaker_dump.dart
@@ -32,7 +32,7 @@
 String usage = '''
 Usage: treeshaker_dump [options] FILE.dill
 
-Runs tree shaking on the given program and prints information about the results.
+Runs tree shaking on the given component and prints information about the results.
 
 Example:
   treeshaker_dump --instantiated foo.dill
@@ -65,11 +65,11 @@
 
   bool strong = options['strong'];
 
-  Program program = loadProgramFromBinary(filename);
-  CoreTypes coreTypes = new CoreTypes(program);
-  ClassHierarchy hierarchy = new ClassHierarchy(program);
+  Component component = loadComponentFromBinary(filename);
+  CoreTypes coreTypes = new CoreTypes(component);
+  ClassHierarchy hierarchy = new ClassHierarchy(component);
   TreeShaker shaker =
-      new TreeShaker(coreTypes, hierarchy, program, strongMode: strong);
+      new TreeShaker(coreTypes, hierarchy, component, strongMode: strong);
   int totalClasses = 0;
   int totalInstantiationCandidates = 0;
   int totalMembers = 0;
@@ -92,7 +92,7 @@
     }
   }
 
-  for (var library in program.libraries) {
+  for (var library in component.libraries) {
     library.members.forEach(visitMember);
     for (Class classNode in library.classes) {
       ++totalClasses;
@@ -130,12 +130,12 @@
     String afterFile = pathlib.join(outputDir, '$name.after.txt');
     NameSystem names = new NameSystem();
     StringBuffer before = new StringBuffer();
-    new Printer(before, syntheticNames: names).writeProgramFile(program);
+    new Printer(before, syntheticNames: names).writeComponentFile(component);
     new File(beforeFile).writeAsStringSync('$before');
-    new TreeShaker(coreTypes, hierarchy, program, strongMode: strong)
-        .transform(program);
+    new TreeShaker(coreTypes, hierarchy, component, strongMode: strong)
+        .transform(component);
     StringBuffer after = new StringBuffer();
-    new Printer(after, syntheticNames: names).writeProgramFile(program);
+    new Printer(after, syntheticNames: names).writeComponentFile(component);
     new File(afterFile).writeAsStringSync('$after');
     print('Text written to $beforeFile and $afterFile');
   }
diff --git a/pkg/kernel/test/treeshaker_membench.dart b/pkg/kernel/test/treeshaker_membench.dart
index 596ef87..b4f3dca 100644
--- a/pkg/kernel/test/treeshaker_membench.dart
+++ b/pkg/kernel/test/treeshaker_membench.dart
@@ -23,7 +23,7 @@
 ${argParser.usage}
 """;
 
-/// Builds N copies of the tree shaker data structure for the given program.
+/// Builds N copies of the tree shaker data structure for the given component.
 /// Pass --print-metrics to the Dart VM to measure the memory use.
 main(List<String> args) {
   if (args.length == 0) {
@@ -38,14 +38,14 @@
   String filename = options.rest.single;
   bool strongMode = options['strong'];
 
-  Program program = loadProgramFromBinary(filename);
-  ClassHierarchy hierarchy = new ClassHierarchy(program);
-  CoreTypes coreTypes = new CoreTypes(program);
+  Component component = loadComponentFromBinary(filename);
+  ClassHierarchy hierarchy = new ClassHierarchy(component);
+  CoreTypes coreTypes = new CoreTypes(component);
 
   int copyCount = int.parse(options['count']);
 
   TreeShaker buildTreeShaker() {
-    return new TreeShaker(coreTypes, hierarchy, program,
+    return new TreeShaker(coreTypes, hierarchy, component,
         strongMode: strongMode);
   }
 
diff --git a/pkg/kernel/test/type_hashcode_quality.dart b/pkg/kernel/test/type_hashcode_quality.dart
index 53a2b70..d90183a 100644
--- a/pkg/kernel/test/type_hashcode_quality.dart
+++ b/pkg/kernel/test/type_hashcode_quality.dart
@@ -15,9 +15,9 @@
     print(usage);
     exit(1);
   }
-  Program program = loadProgramFromBinary(args[0]);
+  Component component = loadComponentFromBinary(args[0]);
   var visitor = new DartTypeCollector();
-  program.accept(visitor);
+  component.accept(visitor);
   print('''
 Types:      ${visitor.numberOfTypes}
 Collisions: ${visitor.numberOfCollisions}''');
diff --git a/pkg/kernel/test/type_parser.dart b/pkg/kernel/test/type_parser.dart
index 2d3820b..8599091 100644
--- a/pkg/kernel/test/type_parser.dart
+++ b/pkg/kernel/test/type_parser.dart
@@ -288,11 +288,11 @@
   final Map<String, Class> classes = <String, Class>{};
   final Map<String, TypeParameter> typeParameters = <String, TypeParameter>{};
   Library dummyLibrary;
-  final Program program = new Program();
+  final Component component = new Component();
 
   LazyTypeEnvironment() {
     dummyLibrary = new Library(Uri.parse('file://dummy.dart'));
-    program.libraries.add(dummyLibrary..parent = program);
+    component.libraries.add(dummyLibrary..parent = component);
     dummyLibrary.name = 'lib';
   }
 
diff --git a/pkg/kernel/test/type_subtype_test.dart b/pkg/kernel/test/type_subtype_test.dart
index 29e7bae..a1fb124 100644
--- a/pkg/kernel/test/type_subtype_test.dart
+++ b/pkg/kernel/test/type_subtype_test.dart
@@ -223,8 +223,8 @@
       }
     }
   }
-  var program = new Program(libraries: [environment.dummyLibrary]);
-  var hierarchy = new ClassHierarchy(program);
+  var component = new Component(libraries: [environment.dummyLibrary]);
+  var hierarchy = new ClassHierarchy(component);
   return new MockSubtypeTester(
       hierarchy,
       objectClass.rawType,
diff --git a/pkg/kernel/test/typecheck.dart b/pkg/kernel/test/typecheck.dart
index f8a054b..731378e 100644
--- a/pkg/kernel/test/typecheck.dart
+++ b/pkg/kernel/test/typecheck.dart
@@ -11,7 +11,7 @@
 final String usage = '''
 Usage: typecheck FILE.dill
 
-Runs the strong mode type checker on the given program.
+Runs the strong mode type checker on the given component.
 ''';
 
 main(List<String> args) {
@@ -19,10 +19,10 @@
     print(usage);
     exit(1);
   }
-  var program = loadProgramFromBinary(args[0]);
-  var coreTypes = new CoreTypes(program);
-  var hierarchy = new ClassHierarchy(program);
-  new TestTypeChecker(coreTypes, hierarchy).checkProgram(program);
+  var component = loadComponentFromBinary(args[0]);
+  var coreTypes = new CoreTypes(component);
+  var hierarchy = new ClassHierarchy(component);
+  new TestTypeChecker(coreTypes, hierarchy).checkComponent(component);
 }
 
 class TestTypeChecker extends TypeChecker {
diff --git a/pkg/kernel/test/verify_bench.dart b/pkg/kernel/test/verify_bench.dart
index 17fd65d..c5fc42e 100644
--- a/pkg/kernel/test/verify_bench.dart
+++ b/pkg/kernel/test/verify_bench.dart
@@ -10,7 +10,7 @@
 final String usage = '''
 Usage: verify_bench FILE.dill
 
-Measures the time it takes to run kernel verifier on the given program.
+Measures the time it takes to run kernel verifier on the given component.
 ''';
 
 main(List<String> args) {
@@ -18,18 +18,18 @@
     print(usage);
     exit(1);
   }
-  var program = loadProgramFromBinary(args[0]);
+  var component = loadComponentFromBinary(args[0]);
   var watch = new Stopwatch()..start();
-  verifyProgram(program);
+  verifyComponent(component);
   print('Cold: ${watch.elapsedMilliseconds} ms');
   const int warmUpTrials = 20;
   for (int i = 0; i < warmUpTrials; ++i) {
-    verifyProgram(program);
+    verifyComponent(component);
   }
   watch.reset();
   const int numberOfTrials = 100;
   for (int i = 0; i < numberOfTrials; ++i) {
-    verifyProgram(program);
+    verifyComponent(component);
   }
   double millisecondsPerRun = watch.elapsedMilliseconds / numberOfTrials;
   print('Hot:  $millisecondsPerRun ms');
diff --git a/pkg/kernel/test/verify_self_check.dart b/pkg/kernel/test/verify_self_check.dart
index a9ccbb8..bc9b184 100644
--- a/pkg/kernel/test/verify_self_check.dart
+++ b/pkg/kernel/test/verify_self_check.dart
@@ -9,6 +9,6 @@
 
 main(List<String> args) {
   runSelfCheck(args, (String filename) {
-    verifyProgram(loadProgramFromBinary(filename));
+    verifyComponent(loadComponentFromBinary(filename));
   });
 }
diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart
index 32b80f9..c08e7f7 100644
--- a/pkg/kernel/test/verify_test.dart
+++ b/pkg/kernel/test/verify_test.dart
@@ -11,9 +11,9 @@
 
 const String tvarRegexp = "#T[0-9]+";
 
-/// Checks that the verifier correctly find errors in invalid programs.
+/// Checks that the verifier correctly find errors in invalid components.
 ///
-/// The frontend should never generate invalid programs, so we have to test
+/// The frontend should never generate invalid components, so we have to test
 /// these by manually constructing invalid ASTs.
 ///
 /// We mostly test negative cases here, as we get plenty of positive cases by
@@ -66,7 +66,7 @@
   negativeTest('Class redeclared',
       "Class 'test_lib::OtherClass' declared more than once.",
       (TestHarness test) {
-    return test.otherClass; // Test harness also adds otherClass to program.
+    return test.otherClass; // Test harness also adds otherClass to component.
   });
   negativeTest('Class type parameter redeclared',
       matches("Type parameter 'test_lib::Test::$tvarRegexp' redeclared\\."),
@@ -478,18 +478,18 @@
   });
 }
 
-checkHasError(Program program, Matcher matcher) {
+checkHasError(Component component, Matcher matcher) {
   try {
-    verifyProgram(program);
+    verifyComponent(component);
   } on VerificationError catch (e) {
     expect(e.details, matcher);
     return;
   }
-  fail('Failed to reject invalid program:\n${programToString(program)}');
+  fail('Failed to reject invalid component:\n${componentToString(component)}');
 }
 
 class TestHarness {
-  Program program;
+  Component component;
   Class objectClass;
   Library stubLibrary;
 
@@ -541,18 +541,18 @@
   }
 
   TestHarness() {
-    setupProgram();
+    setupComponent();
   }
 
-  void setupProgram() {
-    program = new Program();
+  void setupComponent() {
+    component = new Component();
     stubLibrary = new Library(Uri.parse('dart:core'));
-    program.libraries.add(stubLibrary..parent = program);
+    component.libraries.add(stubLibrary..parent = component);
     stubLibrary.name = 'dart.core';
     objectClass = new Class(name: 'Object');
     stubLibrary.addClass(objectClass);
     enclosingLibrary = new Library(Uri.parse('file://test.dart'));
-    program.libraries.add(enclosingLibrary..parent = program);
+    component.libraries.add(enclosingLibrary..parent = component);
     enclosingLibrary.name = 'test_lib';
     classTypeParameter = makeTypeParameter('T');
     enclosingClass = new Class(
@@ -578,7 +578,7 @@
   test(name, () {
     var test = new TestHarness();
     test.addNode(makeTestCase(test));
-    checkHasError(test.program, matcher);
+    checkHasError(test.component, matcher);
   });
 }
 
@@ -586,6 +586,6 @@
   test(name, () {
     var test = new TestHarness();
     test.addNode(makeTestCase(test));
-    verifyProgram(test.program);
+    verifyComponent(test.component);
   });
 }
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 4ec3c11..a742edc 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -37,11 +37,12 @@
 front_end/test/fasta/analyze_test: Pass, Slow
 front_end/test/fasta/ast_builder_test: Pass, Slow
 front_end/test/fasta/bootstrap_test: Pass, Slow
-front_end/test/fasta/compile_test: Pass, Slow
+front_end/test/fasta/compile_test: Pass, ExtraSlow
 front_end/test/fasta/outline_test: Pass, Slow
 front_end/test/fasta/rasta/*: SkipByDesign # Anything in rasta is input to fasta unit tests and shouldn't be run as tests.
 front_end/test/fasta/sdk_test: SkipByDesign # sdk_test would take too long to complete, and should be run in a different way.
-front_end/test/fasta/strong_test: Pass, Slow
+front_end/test/fasta/shaker_test: Skip # Issue http://dartbug.com/32531
+front_end/test/fasta/strong_test: Pass, ExtraSlow
 front_end/test/minimal_incremental_kernel_generator_test: Slow, Pass
 front_end/test/whole_program_test: Slow, Pass
 front_end/testcases/*: Skip # These are not tests but input for tests.
@@ -173,11 +174,6 @@
 crypto/test/sha1_test: Slow, Pass
 crypto/test/sha256_test: Slow, Pass
 
-[ $compiler == dart2js && $browser && $fast_startup && $fasta ]
-analysis_server_client/test/analysis_server_client_test: RuntimeError
-js_ast/test/printer_callback_test: RuntimeError
-js_ast/test/string_escape_test: RuntimeError
-
 [ $compiler == dart2js && $checked ]
 crypto/test/base64_test: Slow, Pass
 
diff --git a/pkg/status_file/lib/expectation.dart b/pkg/status_file/lib/expectation.dart
index 937e57f..bedbabd 100644
--- a/pkg/status_file/lib/expectation.dart
+++ b/pkg/status_file/lib/expectation.dart
@@ -122,6 +122,12 @@
   /// Tells the test runner to increase the timeout when running it.
   static final Expectation slow = new Expectation._('Slow', isMeta: true);
 
+  /// A marker that indicates the test takes a lot longer to complete than most
+  /// tests.
+  /// Tells the test runner to increase the timeout when running it.
+  static final Expectation extraSlow =
+      new Expectation._('ExtraSlow', isMeta: true, group: skip);
+
   /// Tells the test runner to not attempt to run the test.
   ///
   /// This means the test runner does not compare the test's actual results with
@@ -176,6 +182,7 @@
     dartkCompileTimeError,
     ok,
     slow,
+    extraSlow,
     skip,
     skipSlow,
     skipByDesign,
diff --git a/pkg/vm/bin/dump_kernel.dart b/pkg/vm/bin/dump_kernel.dart
index 1d0ea77..0f95c9ce 100644
--- a/pkg/vm/bin/dump_kernel.dart
+++ b/pkg/vm/bin/dump_kernel.dart
@@ -4,7 +4,7 @@
 
 import 'dart:io';
 
-import 'package:kernel/kernel.dart' show Program, writeProgramToText;
+import 'package:kernel/kernel.dart' show Component, writeComponentToText;
 import 'package:kernel/binary/ast_from_binary.dart'
     show BinaryBuilderWithMetadata;
 
@@ -30,17 +30,17 @@
   final input = arguments[0];
   final output = arguments[1];
 
-  final program = new Program();
+  final component = new Component();
 
   // Register VM-specific metadata.
-  program.addMetadataRepository(new DirectCallMetadataRepository());
-  program.addMetadataRepository(new InferredTypeMetadataRepository());
-  program.addMetadataRepository(new ProcedureAttributesMetadataRepository());
-  program.addMetadataRepository(new UnreachableNodeMetadataRepository());
+  component.addMetadataRepository(new DirectCallMetadataRepository());
+  component.addMetadataRepository(new InferredTypeMetadataRepository());
+  component.addMetadataRepository(new ProcedureAttributesMetadataRepository());
+  component.addMetadataRepository(new UnreachableNodeMetadataRepository());
 
   final List<int> bytes = new File(input).readAsBytesSync();
-  new BinaryBuilderWithMetadata(bytes).readProgram(program);
+  new BinaryBuilderWithMetadata(bytes).readComponent(component);
 
-  writeProgramToText(program,
+  writeComponentToText(component,
       path: output, showExternal: true, showMetadata: true);
 }
diff --git a/pkg/vm/bin/gen_kernel.dart b/pkg/vm/bin/gen_kernel.dart
index c2571f2..5c17f8f 100644
--- a/pkg/vm/bin/gen_kernel.dart
+++ b/pkg/vm/bin/gen_kernel.dart
@@ -8,7 +8,7 @@
 import 'package:args/args.dart' show ArgParser, ArgResults;
 import 'package:front_end/src/api_prototype/front_end.dart';
 import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/kernel.dart' show Program;
+import 'package:kernel/kernel.dart' show Component;
 import 'package:kernel/src/tool/batch_util.dart' as batch_util;
 import 'package:kernel/target/targets.dart' show TargetFlags;
 import 'package:kernel/target/vm.dart' show VmTarget;
@@ -29,15 +29,14 @@
   ..addFlag('strong-mode', help: 'Enable strong mode', defaultsTo: true)
   ..addFlag('sync-async', help: 'Start `async` functions synchronously')
   ..addFlag('embed-sources',
-      help: 'Embed source files in the generated kernel program',
+      help: 'Embed source files in the generated kernel component',
       defaultsTo: true)
   ..addFlag('tfa',
       help:
           'Enable global type flow analysis and related transformations in AOT mode.',
       defaultsTo: true)
-  ..addOption('entry-points',
-      help: 'Path to JSON file with the list of entry points',
-      allowMultiple: true);
+  ..addMultiOption('entry-points',
+      help: 'Path to JSON file with the list of entry points');
 
 final String _usage = '''
 Usage: dart pkg/vm/bin/gen_kernel.dart --platform vm_platform_strong.dill [options] input.dart
@@ -99,17 +98,17 @@
     ..onError = errorDetector
     ..embedSourceText = options['embed-sources'];
 
-  Program program = await compileToKernel(
+  Component component = await compileToKernel(
       Uri.base.resolveUri(new Uri.file(filename)), compilerOptions,
       aot: aot, useGlobalTypeFlowAnalysis: tfa, entryPoints: entryPoints);
 
-  if (errorDetector.hasCompilationErrors || (program == null)) {
+  if (errorDetector.hasCompilationErrors || (component == null)) {
     return _compileTimeErrorExitCode;
   }
 
   final IOSink sink = new File(kernelBinaryFilename).openWrite();
   final BinaryPrinter printer = new BinaryPrinter(sink);
-  printer.writeProgramFile(program);
+  printer.writeComponentFile(component);
   await sink.close();
 
   return 0;
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 7423661..a839ff4 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -33,7 +33,7 @@
     show computePlatformBinariesLocation;
 import 'package:front_end/src/fasta/kernel/utils.dart';
 import 'package:front_end/src/testing/hybrid_file_system.dart';
-import 'package:kernel/kernel.dart' show Program;
+import 'package:kernel/kernel.dart' show Component;
 import 'package:kernel/target/targets.dart' show TargetFlags;
 import 'package:kernel/target/vm.dart' show VmTarget;
 import 'package:vm/incremental_compiler.dart';
@@ -109,11 +109,11 @@
       };
   }
 
-  Future<Program> compile(Uri script) {
+  Future<Component> compile(Uri script) {
     return runWithPrintToStderr(() => compileInternal(script));
   }
 
-  Future<Program> compileInternal(Uri script);
+  Future<Component> compileInternal(Uri script);
 }
 
 class IncrementalCompilerWrapper extends Compiler {
@@ -127,7 +127,7 @@
             syncAsync: syncAsync);
 
   @override
-  Future<Program> compileInternal(Uri script) async {
+  Future<Component> compileInternal(Uri script) async {
     if (generator == null) {
       generator = new IncrementalCompiler(options, script);
     }
@@ -153,10 +153,10 @@
             syncAsync: syncAsync);
 
   @override
-  Future<Program> compileInternal(Uri script) async {
+  Future<Component> compileInternal(Uri script) async {
     return requireMain
         ? kernelForProgram(script, options)
-        : kernelForBuildUnit([script], options..chaseDependencies = true);
+        : kernelForComponent([script], options..chaseDependencies = true);
   }
 }
 
@@ -306,19 +306,19 @@
       print("DFE: scriptUri: ${script}");
     }
 
-    Program program = await compiler.compile(script);
+    Component component = await compiler.compile(script);
 
     if (compiler.errors.isNotEmpty) {
       // TODO(sigmund): the compiler prints errors to the console, so we
       // shouldn't print those messages again here.
       result = new CompilationResult.errors(compiler.errors);
     } else {
-      // We serialize the program excluding vm_platform.dill because the VM has
+      // We serialize the component excluding vm_platform.dill because the VM has
       // these sources built-in. Everything loaded as a summary in
       // [kernelForProgram] is marked `external`, so we can use that bit to
       // decide what to exclude.
       result = new CompilationResult.ok(
-          serializeProgram(program, filter: (lib) => !lib.isExternal));
+          serializeComponent(component, filter: (lib) => !lib.isExternal));
     }
   } catch (error, stack) {
     result = new CompilationResult.crash(error, stack);
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index 4abf53c..15ee47f 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -17,10 +17,14 @@
 import 'package:front_end/src/api_prototype/compiler_options.dart';
 import 'package:front_end/src/api_prototype/file_system.dart'
     show FileSystemEntity;
+// Use of multi_root_file_system.dart directly from front_end package is a
+// temporarily solution while we are looking for better home for that
+// functionality.
+import 'package:front_end/src/multi_root_file_system.dart';
 import 'package:kernel/ast.dart';
 import 'package:kernel/binary/ast_to_binary.dart';
 import 'package:kernel/binary/limited_ast_to_binary.dart';
-import 'package:kernel/kernel.dart' show Program, loadProgramFromBytes;
+import 'package:kernel/kernel.dart' show Component, loadComponentFromBytes;
 import 'package:kernel/target/targets.dart';
 import 'package:path/path.dart' as path;
 import 'package:usage/uuid/uuid.dart';
@@ -47,9 +51,8 @@
       help:
           'Enable global type flow analysis and related transformations in AOT mode.',
       defaultsTo: false)
-  ..addOption('entry-points',
-      help: 'Path to JSON file with the list of entry points',
-      allowMultiple: true)
+  ..addMultiOption('entry-points',
+      help: 'Path to JSON file with the list of entry points')
   ..addFlag('link-platform',
       help:
           'When in batch mode, link platform kernel file into result kernel file.'
@@ -68,7 +71,18 @@
   ..addOption('target',
       help: 'Target model that determines what core libraries are available',
       allowed: <String>['vm', 'flutter'],
-      defaultsTo: 'vm');
+      defaultsTo: 'vm')
+  ..addMultiOption('filesystem-root',
+      help: 'File path that is used as a root in virtual filesystem used in'
+          ' compiled kernel files. When used --output-dill should be provided'
+          ' as well.',
+      hide: true)
+  ..addOption('filesystem-scheme',
+      help:
+          'Scheme that is used in virtual filesystem set up via --filesystem-root'
+          ' option',
+      defaultsTo: 'org-dartlang-root',
+      hide: true);
 
 String usage = '''
 Usage: server [options] [input.dart]
@@ -128,7 +142,7 @@
 }
 
 abstract class ProgramTransformer {
-  void transform(Program program);
+  void transform(Component component);
 }
 
 /// Class that for test mocking purposes encapsulates creation of [BinaryPrinter].
@@ -162,7 +176,7 @@
   final ProgramTransformer transformer;
 
   void setMainSourceFilename(String filename) {
-    final Uri filenameUri = Uri.base.resolveUri(new Uri.file(filename));
+    final Uri filenameUri = _getFileOrUri(filename);
     _mainSource = filenameUri;
   }
 
@@ -187,24 +201,37 @@
         (options['strong'] ? 'platform_strong.dill' : 'platform.dill');
     final CompilerOptions compilerOptions = new CompilerOptions()
       ..sdkRoot = sdkRoot
-      ..packagesFileUri = options['packages'] != null
-          ? Uri.base.resolveUri(new Uri.file(options['packages']))
-          : null
+      ..packagesFileUri = _getFileOrUri(_options['packages'])
       ..strongMode = options['strong']
       ..sdkSummary = sdkRoot.resolve(platformKernelDill)
       ..reportMessages = true;
+    if (options.wasParsed('filesystem-root')) {
+      List<Uri> rootUris = <Uri>[];
+      for (String root in options['filesystem-root']) {
+        rootUris.add(Uri.base.resolveUri(new Uri.file(root)));
+      }
+      compilerOptions.fileSystem = new MultiRootFileSystem(
+          options['filesystem-scheme'], rootUris, compilerOptions.fileSystem);
+
+      if (_options['output-dill'] == null) {
+        print("When --filesystem-root is specified it is required to specify"
+            " --output-dill option that points to physical file system location"
+            " of a target dill file.");
+        exit(1);
+      }
+    }
 
     final TargetFlags targetFlags =
         new TargetFlags(strongMode: options['strong']);
     compilerOptions.target = getTarget(options['target'], targetFlags);
 
-    Program program;
+    Component component;
     if (options['incremental']) {
       _compilerOptions = compilerOptions;
       _generator = generator ??
           _createGenerator(new Uri.file(_kernelBinaryFilenameFull));
       await invalidateIfBootstrapping();
-      program = await _runWithPrintRedirection(() => _generator.compile());
+      component = await _runWithPrintRedirection(() => _generator.compile());
     } else {
       if (options['link-platform']) {
         // TODO(aam): Remove linkedDependencies once platform is directly embedded
@@ -213,26 +240,26 @@
           sdkRoot.resolve(platformKernelDill)
         ];
       }
-      program = await _runWithPrintRedirection(() => compileToKernel(
+      component = await _runWithPrintRedirection(() => compileToKernel(
           _mainSource, compilerOptions,
           aot: options['aot'],
           useGlobalTypeFlowAnalysis: options['tfa'],
           entryPoints: options['entry-points']));
     }
-    if (program != null) {
+    if (component != null) {
       if (transformer != null) {
-        transformer.transform(program);
+        transformer.transform(component);
       }
 
       final IOSink sink = new File(_kernelBinaryFilename).openWrite();
       final BinaryPrinter printer = printerFactory.newBinaryPrinter(sink);
-      printer.writeProgramFile(program);
+      printer.writeComponentFile(component);
       await sink.close();
       _outputStream.writeln('$boundaryKey $_kernelBinaryFilename');
 
       final String depfile = options['depfile'];
       if (depfile != null) {
-        await _writeDepfile(program, _kernelBinaryFilename, depfile);
+        await _writeDepfile(component, _kernelBinaryFilename, depfile);
       }
 
       _kernelBinaryFilename = _kernelBinaryFilenameIncremental;
@@ -248,11 +275,11 @@
       final File f = new File(_kernelBinaryFilenameFull);
       if (!f.existsSync()) return null;
 
-      final Program program = loadProgramFromBytes(f.readAsBytesSync());
-      for (Uri uri in program.uriToSource.keys) {
+      final Component component = loadComponentFromBytes(f.readAsBytesSync());
+      for (Uri uri in component.uriToSource.keys) {
         if ('$uri' == '') continue;
 
-        final List<int> oldBytes = program.uriToSource[uri].source;
+        final List<int> oldBytes = component.uriToSource[uri].source;
         final FileSystemEntity entity =
             _compilerOptions.fileSystem.entityForUri(uri);
         if (!await entity.exists()) {
@@ -287,7 +314,7 @@
     if (filename != null) {
       setMainSourceFilename(filename);
     }
-    final Program deltaProgram =
+    final Component deltaProgram =
         await _generator.compile(entryPoint: _mainSource);
 
     if (deltaProgram != null && transformer != null) {
@@ -296,7 +323,7 @@
 
     final IOSink sink = new File(_kernelBinaryFilename).openWrite();
     final BinaryPrinter printer = printerFactory.newBinaryPrinter(sink);
-    printer.writeProgramFile(deltaProgram);
+    printer.writeComponentFile(deltaProgram);
     await sink.close();
     _outputStream.writeln('$boundaryKey $_kernelBinaryFilename');
     _kernelBinaryFilename = _kernelBinaryFilenameIncremental;
@@ -319,6 +346,22 @@
     _kernelBinaryFilename = _kernelBinaryFilenameFull;
   }
 
+  Uri _getFileOrUri(String fileOrUri) {
+    if (fileOrUri == null) {
+      return null;
+    }
+    if (_options.wasParsed('filesystem-root')) {
+      // This is a hack.
+      // Only expect uri when filesystem-root option is specified. It has to
+      // be uri for filesystem-root use case because mapping is done on
+      // scheme-basis.
+      // This is so that we don't deal with Windows files paths that can not
+      // be processed as uris.
+      return Uri.base.resolve(fileOrUri);
+    }
+    return Uri.base.resolveUri(new Uri.file(fileOrUri));
+  }
+
   IncrementalCompiler _createGenerator(Uri bootstrapDill) {
     return new IncrementalCompiler(_compilerOptions, _mainSource,
         bootstrapDill: bootstrapDill);
@@ -347,11 +390,11 @@
 }
 
 // https://ninja-build.org/manual.html#_depfile
-void _writeDepfile(Program program, String output, String depfile) async {
+void _writeDepfile(Component component, String output, String depfile) async {
   final IOSink file = new File(depfile).openWrite();
   file.write(_escapePath(output));
   file.write(':');
-  for (Uri dep in program.uriToSource.keys) {
+  for (Uri dep in component.uriToSource.keys) {
     file.write(' ');
     file.write(_escapePath(dep.toFilePath()));
   }
@@ -368,7 +411,7 @@
   String boundaryKey;
   String recompileFilename;
   input
-      .transform(UTF8.decoder)
+      .transform(utf8.decoder)
       .transform(const LineSplitter())
       .listen((String string) async {
     switch (state) {
diff --git a/pkg/vm/lib/incremental_compiler.dart b/pkg/vm/lib/incremental_compiler.dart
index ac51130..bfe5919 100644
--- a/pkg/vm/lib/incremental_compiler.dart
+++ b/pkg/vm/lib/incremental_compiler.dart
@@ -15,32 +15,32 @@
 /// accepted.
 class IncrementalCompiler {
   IncrementalKernelGenerator _generator;
-  List<Program> _pendingDeltas;
+  List<Component> _pendingDeltas;
   CompilerOptions _compilerOptions;
 
   IncrementalCompiler(this._compilerOptions, Uri entryPoint,
       {Uri bootstrapDill}) {
     _generator = new IncrementalKernelGenerator(
         _compilerOptions, entryPoint, bootstrapDill);
-    _pendingDeltas = <Program>[];
+    _pendingDeltas = <Component>[];
   }
 
-  /// Recompiles invalidated files, produces incremental program.
+  /// Recompiles invalidated files, produces incremental component.
   ///
   /// If [entryPoint] is specified, that points to new entry point for the
   /// compilation. Otherwise, previously set entryPoint is used.
-  Future<Program> compile({Uri entryPoint}) async {
-    Program program = await _generator.computeDelta(entryPoint: entryPoint);
+  Future<Component> compile({Uri entryPoint}) async {
+    Component component = await _generator.computeDelta(entryPoint: entryPoint);
     final bool firstDelta = _pendingDeltas.isEmpty;
-    _pendingDeltas.add(program);
+    _pendingDeltas.add(component);
     if (firstDelta) {
-      return program;
+      return component;
     }
 
     // If more than one delta is pending, we need to combine them.
     Procedure mainMethod;
     Map<Uri, Library> combined = <Uri, Library>{};
-    for (Program delta in _pendingDeltas) {
+    for (Component delta in _pendingDeltas) {
       if (delta.mainMethod != null) {
         mainMethod = delta.mainMethod;
       }
@@ -48,7 +48,7 @@
         combined[library.importUri] = library;
       }
     }
-    return new Program(libraries: combined.values.toList())
+    return new Component(libraries: combined.values.toList())
       ..mainMethod = mainMethod;
   }
 
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index e7c9030..aae78b5 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -14,22 +14,22 @@
 import 'package:front_end/src/api_prototype/compilation_message.dart'
     show CompilationMessage, Severity;
 import 'package:front_end/src/fasta/severity.dart' show Severity;
-import 'package:kernel/ast.dart' show Program;
+import 'package:kernel/ast.dart' show Component;
 import 'package:kernel/core_types.dart' show CoreTypes;
 
 import 'transformations/devirtualization.dart' as devirtualization
-    show transformProgram;
+    show transformComponent;
 import 'transformations/no_dynamic_invocations_annotator.dart'
-    as no_dynamic_invocations_annotator show transformProgram;
+    as no_dynamic_invocations_annotator show transformComponent;
 import 'transformations/type_flow/transformer.dart' as globalTypeFlow
-    show transformProgram;
+    show transformComponent;
 
 /// Generates a kernel representation of the program whose main library is in
 /// the given [source]. Intended for whole program (non-modular) compilation.
 ///
 /// VM-specific replacement of [kernelForProgram].
 ///
-Future<Program> compileToKernel(Uri source, CompilerOptions options,
+Future<Component> compileToKernel(Uri source, CompilerOptions options,
     {bool aot: false,
     bool useGlobalTypeFlowAnalysis: false,
     List<String> entryPoints}) async {
@@ -38,32 +38,32 @@
       new ErrorDetector(previousErrorHandler: options.onError);
   options.onError = errorDetector;
 
-  final program = await kernelForProgram(source, options);
+  final component = await kernelForProgram(source, options);
 
   // Restore error handler (in case 'options' are reused).
   options.onError = errorDetector.previousErrorHandler;
 
-  // Run global transformations only if program is correct.
-  if (aot && (program != null) && !errorDetector.hasCompilationErrors) {
+  // Run global transformations only if component is correct.
+  if (aot && (component != null) && !errorDetector.hasCompilationErrors) {
     _runGlobalTransformations(
-        program, options.strongMode, useGlobalTypeFlowAnalysis, entryPoints);
+        component, options.strongMode, useGlobalTypeFlowAnalysis, entryPoints);
   }
 
-  return program;
+  return component;
 }
 
-_runGlobalTransformations(Program program, bool strongMode,
+_runGlobalTransformations(Component component, bool strongMode,
     bool useGlobalTypeFlowAnalysis, List<String> entryPoints) {
   if (strongMode) {
-    final coreTypes = new CoreTypes(program);
+    final coreTypes = new CoreTypes(component);
 
     if (useGlobalTypeFlowAnalysis) {
-      globalTypeFlow.transformProgram(coreTypes, program, entryPoints);
+      globalTypeFlow.transformComponent(coreTypes, component, entryPoints);
     } else {
-      devirtualization.transformProgram(coreTypes, program);
+      devirtualization.transformComponent(coreTypes, component);
     }
 
-    no_dynamic_invocations_annotator.transformProgram(program);
+    no_dynamic_invocations_annotator.transformComponent(component);
   }
 }
 
diff --git a/pkg/vm/lib/transformations/devirtualization.dart b/pkg/vm/lib/transformations/devirtualization.dart
index 0e03957..479755d 100644
--- a/pkg/vm/lib/transformations/devirtualization.dart
+++ b/pkg/vm/lib/transformations/devirtualization.dart
@@ -13,12 +13,13 @@
 
 /// Devirtualization of method invocations based on the class hierarchy
 /// analysis. Assumes strong mode and closed world.
-Program transformProgram(CoreTypes coreTypes, Program program) {
+Component transformComponent(CoreTypes coreTypes, Component component) {
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
-  final hierarchy = new ClassHierarchy(program,
+  final hierarchy = new ClassHierarchy(component,
       onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
-  new CHADevirtualization(coreTypes, program, hierarchy).visitProgram(program);
-  return program;
+  new CHADevirtualization(coreTypes, component, hierarchy)
+      .visitComponent(component);
+  return component;
 }
 
 /// Base class for implementing devirtualization of method invocations.
@@ -33,12 +34,12 @@
   Set<Name> _objectMemberNames;
 
   Devirtualization(
-      CoreTypes coreTypes, Program program, ClassHierarchy hierarchy)
+      CoreTypes coreTypes, Component component, ClassHierarchy hierarchy)
       : _metadata = new DirectCallMetadataRepository() {
     _objectMemberNames = new Set<Name>.from(hierarchy
         .getInterfaceMembers(coreTypes.objectClass)
         .map((Member m) => m.name));
-    program.addMetadataRepository(_metadata);
+    component.addMetadataRepository(_metadata);
   }
 
   bool isMethod(Member member) => (member is Procedure) && !member.isGetter;
@@ -141,8 +142,8 @@
 class CHADevirtualization extends Devirtualization {
   final ClosedWorldClassHierarchy _hierarchy;
 
-  CHADevirtualization(CoreTypes coreTypes, Program program, this._hierarchy)
-      : super(coreTypes, program, _hierarchy);
+  CHADevirtualization(CoreTypes coreTypes, Component component, this._hierarchy)
+      : super(coreTypes, component, _hierarchy);
 
   @override
   DirectCallMetadata getDirectCall(TreeNode node, Member target,
diff --git a/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart b/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
index a176469..00e93ff 100644
--- a/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
+++ b/pkg/vm/lib/transformations/no_dynamic_invocations_annotator.dart
@@ -11,9 +11,9 @@
 /// Assumes strong mode and closed world. If a procedure can not be riched
 /// via dynamic invocation from anywhere then annotates it with appropriate
 /// [ProcedureAttributeMetadata] annotation.
-Program transformProgram(Program program) {
-  new NoDynamicUsesAnnotator(program).visitProgram(program);
-  return program;
+Component transformComponent(Component component) {
+  new NoDynamicUsesAnnotator(component).visitComponent(component);
+  return component;
 }
 
 enum Action { get, set, invoke }
@@ -56,14 +56,14 @@
   final DynamicSelectorsCollector _selectors;
   final ProcedureAttributesMetadataRepository _metadata;
 
-  NoDynamicUsesAnnotator(Program program)
-      : _selectors = DynamicSelectorsCollector.collect(program),
+  NoDynamicUsesAnnotator(Component component)
+      : _selectors = DynamicSelectorsCollector.collect(component),
         _metadata = new ProcedureAttributesMetadataRepository() {
-    program.addMetadataRepository(_metadata);
+    component.addMetadataRepository(_metadata);
   }
 
-  visitProgram(Program program) {
-    for (var library in program.libraries) {
+  visitComponent(Component component) {
+    for (var library in component.libraries) {
       for (var klass in library.classes) {
         visitClass(klass);
       }
@@ -142,14 +142,14 @@
   final Set<Selector> nonThisSelectors = new Set<Selector>();
   final Set<Selector> tearOffSelectors = new Set<Selector>();
 
-  static DynamicSelectorsCollector collect(Program program) {
+  static DynamicSelectorsCollector collect(Component component) {
     final v = new DynamicSelectorsCollector();
-    v.visitProgram(program);
+    v.visitComponent(component);
 
     // We only populate [nonThisSelectors] and [tearOffSelectors] inside the
-    // non-dynamic case (for efficiency reasons) while visiting the [Program].
+    // non-dynamic case (for efficiency reasons) while visiting the [Component].
     //
-    // After the recursive visit of [Program] we complete the sets here.
+    // After the recursive visit of [Component] we complete the sets here.
     for (final Selector selector in v.dynamicSelectors) {
       // All dynamic getters can be tearoffs.
       if (selector.action == Action.get) {
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 8dd75bc..4fa8d46 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -5,7 +5,7 @@
 /// Handling of native code and entry points.
 library vm.transformations.type_flow.native_code;
 
-import 'dart:convert' show JSON;
+import 'dart:convert' show json;
 import 'dart:core' hide Type;
 import 'dart:io' show File;
 
@@ -183,16 +183,16 @@
   /// 'runtime/vm/compiler/aot/entry_points_json.md'.
   void processEntryPointsJSON(
       String jsonString, EntryPointsListener entryPointsListener) {
-    final json = JSON.decode(jsonString);
+    final jsonObject = json.decode(jsonString);
 
-    final roots = json['roots'];
+    final roots = jsonObject['roots'];
     if (roots != null) {
       for (var root in roots) {
         _addRoot(new Map<String, String>.from(root), entryPointsListener);
       }
     }
 
-    final nativeMethods = json['native-methods'];
+    final nativeMethods = jsonObject['native-methods'];
     if (nativeMethods != null) {
       nativeMethods.forEach((name, actions) {
         _nativeMethods[name] = new List<Map<String, dynamic>>.from(
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 94a6d37..11af8c3 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -973,6 +973,12 @@
   }
 
   @override
+  TypeExpr visitAssertBlock(AssertBlock node) {
+    node.statements.forEach(_visit);
+    return null;
+  }
+
+  @override
   TypeExpr visitBreakStatement(BreakStatement node) => null;
 
   @override
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 7d5480c..52f1055 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -30,21 +30,21 @@
 
 /// Whole-program type flow analysis and transformation.
 /// Assumes strong mode and closed world.
-Program transformProgram(
-    CoreTypes coreTypes, Program program, List<String> entryPoints) {
+Component transformComponent(
+    CoreTypes coreTypes, Component component, List<String> entryPoints) {
   if ((entryPoints == null) || entryPoints.isEmpty) {
     throw 'Error: unable to perform global type flow analysis without entry points.';
   }
 
   void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
-  final hierarchy = new ClassHierarchy(program,
+  final hierarchy = new ClassHierarchy(component,
       onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
   final types = new TypeEnvironment(coreTypes, hierarchy, strongMode: true);
-  final libraryIndex = new LibraryIndex.all(program);
+  final libraryIndex = new LibraryIndex.all(component);
 
   if (kDumpAllSummaries) {
     Statistics.reset();
-    new CreateAllSummariesVisitor(types).visitProgram(program);
+    new CreateAllSummariesVisitor(types).visitComponent(component);
     Statistics.print("All summaries statistics");
   }
 
@@ -54,7 +54,7 @@
   final typeFlowAnalysis = new TypeFlowAnalysis(hierarchy, types, libraryIndex,
       entryPointsJSONFiles: entryPoints);
 
-  Procedure main = program.mainMethod;
+  Procedure main = component.mainMethod;
   final Selector mainSelector = new DirectSelector(main);
   typeFlowAnalysis.addRawCall(mainSelector);
   typeFlowAnalysis.process();
@@ -67,11 +67,12 @@
 
   final transformsStopWatch = new Stopwatch()..start();
 
-  new DropMethodBodiesVisitor(typeFlowAnalysis).visitProgram(program);
+  new DropMethodBodiesVisitor(typeFlowAnalysis).visitComponent(component);
 
-  new TFADevirtualization(program, typeFlowAnalysis).visitProgram(program);
+  new TFADevirtualization(component, typeFlowAnalysis)
+      .visitComponent(component);
 
-  new AnnotateKernel(program, typeFlowAnalysis).visitProgram(program);
+  new AnnotateKernel(component, typeFlowAnalysis).visitComponent(component);
 
   transformsStopWatch.stop();
 
@@ -80,15 +81,15 @@
 
   Statistics.print("TFA statistics");
 
-  return program;
+  return component;
 }
 
 /// Devirtualization based on results of type flow analysis.
 class TFADevirtualization extends Devirtualization {
   final TypeFlowAnalysis _typeFlowAnalysis;
 
-  TFADevirtualization(Program program, this._typeFlowAnalysis)
-      : super(_typeFlowAnalysis.environment.coreTypes, program,
+  TFADevirtualization(Component component, this._typeFlowAnalysis)
+      : super(_typeFlowAnalysis.environment.coreTypes, component,
             _typeFlowAnalysis.environment.hierarchy);
 
   @override
@@ -138,11 +139,11 @@
   final InferredTypeMetadataRepository _inferredTypeMetadata;
   final UnreachableNodeMetadataRepository _unreachableNodeMetadata;
 
-  AnnotateKernel(Program program, this._typeFlowAnalysis)
+  AnnotateKernel(Component component, this._typeFlowAnalysis)
       : _inferredTypeMetadata = new InferredTypeMetadataRepository(),
         _unreachableNodeMetadata = new UnreachableNodeMetadataRepository() {
-    program.addMetadataRepository(_inferredTypeMetadata);
-    program.addMetadataRepository(_unreachableNodeMetadata);
+    component.addMetadataRepository(_inferredTypeMetadata);
+    component.addMetadataRepository(_unreachableNodeMetadata);
   }
 
   InferredType _convertType(Type type) {
diff --git a/pkg/vm/test/frontend_server_test.dart b/pkg/vm/test/frontend_server_test.dart
index 1e4f4c1..3279881 100644
--- a/pkg/vm/test/frontend_server_test.dart
+++ b/pkg/vm/test/frontend_server_test.dart
@@ -5,7 +5,7 @@
 
 import 'package:args/src/arg_results.dart';
 import 'package:kernel/binary/ast_to_binary.dart';
-import 'package:kernel/ast.dart' show Program;
+import 'package:kernel/ast.dart' show Component;
 import 'package:mockito/mockito.dart';
 import 'package:test/test.dart';
 import 'package:vm/incremental_compiler.dart';
@@ -359,7 +359,7 @@
 
       String boundaryKey;
       stdoutStreamController.stream
-          .transform(UTF8.decoder)
+          .transform(utf8.decoder)
           .transform(const LineSplitter())
           .listen((String s) {
         const String RESULT_OUTPUT_SPACE = 'result ';
@@ -378,7 +378,7 @@
       final _MockedIncrementalCompiler generator =
           new _MockedIncrementalCompiler();
       when(generator.compile())
-          .thenAnswer((_) => new Future<Program>.value(new Program()));
+          .thenAnswer((_) => new Future<Component>.value(new Component()));
       final _MockedBinaryPrinterFactory printerFactory =
           new _MockedBinaryPrinterFactory();
       when(printerFactory.newBinaryPrinter(any))
@@ -466,7 +466,7 @@
 
       String boundaryKey;
       stdoutStreamController.stream
-          .transform(UTF8.decoder)
+          .transform(utf8.decoder)
           .transform(const LineSplitter())
           .listen((String s) {
         const String RESULT_OUTPUT_SPACE = 'result ';
@@ -512,6 +512,29 @@
       });
       expect(await allDone.future, true);
     });
+
+    test('compile and recompile with MultiRootFileSystem', () async {
+      var file = new File('${tempDir.path}/foo.dart')..createSync();
+      file.writeAsStringSync("main() {}\n");
+      new File('${tempDir.path}/.packages')
+        ..createSync()
+        ..writeAsStringSync("\n");
+      var dillFile = new File('${tempDir.path}/app.dill');
+      expect(dillFile.existsSync(), equals(false));
+      final List<String> args = <String>[
+        '--sdk-root=${sdkRoot.toFilePath()}',
+        '--strong',
+        '--incremental',
+        '--platform=${platformKernel.path}',
+        '--output-dill=${dillFile.path}',
+        '--packages=test-scheme:///.packages',
+        '--filesystem-root=${tempDir.path}',
+        '--filesystem-scheme=test-scheme',
+        'test-scheme:///foo.dart'
+      ];
+      int exitcode = await starter(args);
+      expect(exitcode, equals(0));
+    });
   });
   return 0;
 }
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index 1e9dc9a..3736600 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -42,11 +42,11 @@
       file.writeAsStringSync("main() {}\n");
 
       IncrementalCompiler compiler = new IncrementalCompiler(options, file.uri);
-      Program program = await compiler.compile();
+      Component component = await compiler.compile();
 
       final StringBuffer buffer = new StringBuffer();
       new Printer(buffer, showExternal: false, showMetadata: true)
-          .writeLibraryFile(program.mainMethod.enclosingLibrary);
+          .writeLibraryFile(component.mainMethod.enclosingLibrary);
       expect(
           buffer.toString(),
           equals('library;\n'
@@ -75,10 +75,10 @@
           "openReceivePortSoWeWontDie() { new RawReceivePort(); }\n");
 
       IncrementalCompiler compiler = new IncrementalCompiler(options, file.uri);
-      Program program = await compiler.compile();
+      Component component = await compiler.compile();
 
       File outputFile = new File('${systemTempDir.path}/foo.dart.dill');
-      await _writeProgramToFile(program, outputFile);
+      await _writeProgramToFile(component, outputFile);
 
       final List<String> vmArgs = [
         '--trace_reload',
@@ -96,7 +96,7 @@
       });
 
       Completer<String> portLineCompleter = new Completer<String>();
-      vm.stdout.transform(UTF8.decoder).transform(splitter).listen((String s) {
+      vm.stdout.transform(utf8.decoder).transform(splitter).listen((String s) {
         print("vm stdout: $s");
         if (!portLineCompleter.isCompleted) {
           portLineCompleter.complete(s);
@@ -104,7 +104,7 @@
       });
 
       vm.stderr
-          .transform(UTF8.decoder)
+          .transform(utf8.decoder)
           .transform(splitter)
           .toList()
           .then((err) {
@@ -126,8 +126,8 @@
       compiler.accept();
 
       // Confirm that without changes VM reloads nothing.
-      program = await compiler.compile();
-      await _writeProgramToFile(program, outputFile);
+      component = await compiler.compile();
+      await _writeProgramToFile(component, outputFile);
       var reloadResult = await remoteVm.reload(new Uri.file(outputFile.path));
       expect(reloadResult['success'], isTrue);
       expect(reloadResult['details']['loadedLibraryCount'], equals(0));
@@ -135,16 +135,16 @@
       // Introduce a change that force VM to reject the change.
       fileBar.writeAsStringSync("class A<T,U> { int _a; }\n");
       compiler.invalidate(fileBar.uri);
-      program = await compiler.compile();
-      await _writeProgramToFile(program, outputFile);
+      component = await compiler.compile();
+      await _writeProgramToFile(component, outputFile);
       reloadResult = await remoteVm.reload(new Uri.file(outputFile.path));
       expect(reloadResult['success'], isFalse);
 
       // Fix a change so VM is happy to accept the change.
       fileBar.writeAsStringSync("class A<T> { int _a; hi() => _a; }\n");
       compiler.invalidate(fileBar.uri);
-      program = await compiler.compile();
-      await _writeProgramToFile(program, outputFile);
+      component = await compiler.compile();
+      await _writeProgramToFile(component, outputFile);
       reloadResult = await remoteVm.reload(new Uri.file(outputFile.path));
       expect(reloadResult['success'], isTrue);
       expect(reloadResult['details']['loadedLibraryCount'], equals(2));
@@ -155,11 +155,11 @@
   });
 }
 
-_writeProgramToFile(Program program, File outputFile) async {
+_writeProgramToFile(Component component, File outputFile) async {
   final IOSink sink = outputFile.openWrite();
   final BinaryPrinter printer = new LimitedBinaryPrinter(
       sink, (_) => true /* predicate */, false /* excludeUriToSource */);
-  printer.writeProgramFile(program);
+  printer.writeComponentFile(component);
   await sink.close();
 }
 
diff --git a/pkg/vm/test/transformations/type_flow/common_test_utils.dart b/pkg/vm/test/transformations/type_flow/common_test_utils.dart
index 01834d6..cdac3b9 100644
--- a/pkg/vm/test/transformations/type_flow/common_test_utils.dart
+++ b/pkg/vm/test/transformations/type_flow/common_test_utils.dart
@@ -15,7 +15,7 @@
 
 const bool kDumpActualResult = const bool.fromEnvironment('dump.actual.result');
 
-Future<Program> compileTestCaseToKernelProgram(Uri sourceUri) async {
+Future<Component> compileTestCaseToKernelProgram(Uri sourceUri) async {
   final platformKernel =
       computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
   final options = new CompilerOptions()
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
index bdd8af1..9d4499b 100644
--- a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -40,15 +40,15 @@
 }
 
 runTestCase(Uri source) async {
-  final Program program = await compileTestCaseToKernelProgram(source);
-  final Library library = program.mainMethod.enclosingLibrary;
+  final Component component = await compileTestCaseToKernelProgram(source);
+  final Library library = component.mainMethod.enclosingLibrary;
 
   // Make sure the library name is the same and does not depend on the order
   // of test cases.
   library.name = '#lib';
 
-  final typeEnvironment =
-      new TypeEnvironment(new CoreTypes(program), new ClassHierarchy(program));
+  final typeEnvironment = new TypeEnvironment(
+      new CoreTypes(component), new ClassHierarchy(component));
 
   final actual = new PrintSummaries(typeEnvironment).print(library);
 
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
index 0aa23a6..45a1855 100644
--- a/pkg/vm/test/transformations/type_flow/transformer_test.dart
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -10,38 +10,38 @@
 import 'package:kernel/text/ast_to_text.dart';
 import 'package:test/test.dart';
 import 'package:vm/transformations/type_flow/transformer.dart'
-    show transformProgram;
+    show transformComponent;
 
 import 'common_test_utils.dart';
 
 final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
 
 runTestCase(Uri source) async {
-  Program program = await compileTestCaseToKernelProgram(source);
+  Component component = await compileTestCaseToKernelProgram(source);
 
   // Make sure the library name is the same and does not depend on the order
   // of test cases.
-  program.mainMethod.enclosingLibrary.name = '#lib';
+  component.mainMethod.enclosingLibrary.name = '#lib';
 
-  final coreTypes = new CoreTypes(program);
+  final coreTypes = new CoreTypes(component);
 
   final entryPoints = [
     pkgVmDir + '/lib/transformations/type_flow/entry_points.json',
     pkgVmDir + '/lib/transformations/type_flow/entry_points_extra.json',
   ];
 
-  program = transformProgram(coreTypes, program, entryPoints);
+  component = transformComponent(coreTypes, component, entryPoints);
 
   final StringBuffer buffer = new StringBuffer();
   new Printer(buffer, showExternal: false, showMetadata: true)
-      .writeLibraryFile(program.mainMethod.enclosingLibrary);
+      .writeLibraryFile(component.mainMethod.enclosingLibrary);
   final actual = buffer.toString();
 
   compareResultWithExpectationsFile(source, actual);
 }
 
 main() {
-  group('transform-program', () {
+  group('transform-component', () {
     final testCasesDir = new Directory(
         pkgVmDir + '/testcases/transformations/type_flow/transformer');
 
diff --git a/runtime/bin/console_win.cc b/runtime/bin/console_win.cc
index 6442dc2..6d7511a 100644
--- a/runtime/bin/console_win.cc
+++ b/runtime/bin/console_win.cc
@@ -14,10 +14,6 @@
 
 // These are not always defined in the header files. See:
 // https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
-#ifndef ENABLE_VIRTUAL_TERMINAL_INPUT
-#define ENABLE_VIRTUAL_TERMINAL_INPUT 0x0200
-#endif
-
 #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
 #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
 #endif
@@ -52,6 +48,9 @@
     // Try to set the bits for ANSI support, but swallow any failures.
     saved_stdout_mode_ =
         ModifyMode(STD_OUTPUT_HANDLE, ENABLE_VIRTUAL_TERMINAL_PROCESSING);
+    saved_stderr_mode_ =
+        ModifyMode(STD_ERROR_HANDLE, ENABLE_VIRTUAL_TERMINAL_PROCESSING);
+    saved_stdin_mode_ = ModifyMode(STD_INPUT_HANDLE, 0);
 
     // TODO(28984): Due to issue #29104, we cannot set
     // ENABLE_VIRTUAL_TERMINAL_INPUT here, as it causes ENABLE_PROCESSED_INPUT
@@ -66,6 +65,12 @@
       CleanupDevices("CONOUT$", STD_OUTPUT_HANDLE, saved_stdout_mode_);
       saved_stdout_mode_ = kInvalidFlag;
     }
+    if (saved_stderr_mode_ != kInvalidFlag) {
+      CleanupDevices("CONERR$", STD_ERROR_HANDLE, saved_stderr_mode_);
+    }
+    if (saved_stdin_mode_ != kInvalidFlag) {
+      CleanupDevices("CONIN$", STD_INPUT_HANDLE, saved_stdin_mode_);
+    }
     if (saved_output_cp_ != kInvalidFlag) {
       SetConsoleOutputCP(saved_output_cp_);
       saved_output_cp_ = kInvalidFlag;
@@ -80,6 +85,8 @@
   static int saved_output_cp_;
   static int saved_input_cp_;
   static DWORD saved_stdout_mode_;
+  static DWORD saved_stderr_mode_;
+  static DWORD saved_stdin_mode_;
 
   static BOOL WINAPI SignalHandler(DWORD signal) {
     if (signal == CTRL_C_EVENT) {
@@ -91,8 +98,11 @@
   static DWORD ModifyMode(DWORD handle, DWORD flags) {
     HANDLE h = GetStdHandle(handle);
     DWORD mode;
-    DWORD old_mode = 0;
+    DWORD old_mode = kInvalidFlag;
 
+    /// GetConsoleMode fails if this instance of the VM isn't attached to a
+    /// console. In that case, we'll just return kInvalidFlag and won't try
+    /// to reset the state when we cleanup.
     if ((h != INVALID_HANDLE_VALUE) && GetConsoleMode(h, &mode)) {
       old_mode = mode;
       if (flags != 0) {
@@ -128,6 +138,8 @@
 int ConsoleWin::saved_output_cp_ = ConsoleWin::kInvalidFlag;
 int ConsoleWin::saved_input_cp_ = ConsoleWin::kInvalidFlag;
 DWORD ConsoleWin::saved_stdout_mode_ = ConsoleWin::kInvalidFlag;
+DWORD ConsoleWin::saved_stderr_mode_ = ConsoleWin::kInvalidFlag;
+DWORD ConsoleWin::saved_stdin_mode_ = ConsoleWin::kInvalidFlag;
 
 void Console::SaveConfig() {
   ConsoleWin::Initialize();
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 787bac0..72368ca 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -146,7 +146,7 @@
   V(Socket_RecvFrom, 1)                                                        \
   V(Socket_SendTo, 6)                                                          \
   V(Socket_SetOption, 4)                                                       \
-  V(Socket_SetSocketId, 2)                                                     \
+  V(Socket_SetSocketId, 3)                                                     \
   V(Socket_WriteList, 4)                                                       \
   V(Stdin_ReadByte, 1)                                                         \
   V(Stdin_GetEchoMode, 1)                                                      \
diff --git a/runtime/bin/process_patch.dart b/runtime/bin/process_patch.dart
index 31702f0..e216e63 100644
--- a/runtime/bin/process_patch.dart
+++ b/runtime/bin/process_patch.dart
@@ -106,7 +106,7 @@
       return;
     }
     _id = id;
-    var socket = new _RawSocket(new _NativeSocket.watch(id));
+    var socket = new _RawSocket(new _NativeSocket.watchSignal(id));
     socket.listen((event) {
       if (event == RawSocketEvent.READ) {
         var bytes = socket.read();
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index d33bdc0..c22ee52 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -9,6 +9,7 @@
 #include "bin/io_buffer.h"
 #include "bin/isolate_data.h"
 #include "bin/lockers.h"
+#include "bin/process.h"
 #include "bin/thread.h"
 #include "bin/utils.h"
 
@@ -601,8 +602,16 @@
 
 void FUNCTION_NAME(Socket_SetSocketId)(Dart_NativeArguments args) {
   intptr_t id = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
+  intptr_t type_flag =
+      DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
+  Socket::SocketFinalizer finalizer;
+  if (Socket::IsSignalSocketFlag(type_flag)) {
+    finalizer = Socket::kFinalizerSignal;
+  } else {
+    finalizer = Socket::kFinalizerNormal;
+  }
   Socket::SetSocketIdNativeField(Dart_GetNativeArgument(args, 0), id,
-                                 Socket::kFinalizerNormal);
+                                 finalizer);
 }
 
 void FUNCTION_NAME(ServerSocket_CreateBindListen)(Dart_NativeArguments args) {
@@ -931,6 +940,21 @@
   socket->Release();
 }
 
+static void SignalSocketFinalizer(void* isolate_data,
+                                  Dart_WeakPersistentHandle handle,
+                                  void* data) {
+  Socket* socket = reinterpret_cast<Socket*>(data);
+  if (socket->fd() >= 0) {
+    Process::ClearSignalHandler(socket->fd(), socket->isolate_port());
+    const int64_t flags = 1 << kCloseCommand;
+    socket->Retain();
+    EventHandler::SendFromNative(reinterpret_cast<intptr_t>(socket),
+                                 socket->port(), flags);
+  }
+
+  socket->Release();
+}
+
 void Socket::ReuseSocketIdNativeField(Dart_Handle handle,
                                       Socket* socket,
                                       SocketFinalizer finalizer) {
@@ -950,6 +974,9 @@
     case kFinalizerStdio:
       callback = StdioSocketFinalizer;
       break;
+    case kFinalizerSignal:
+      callback = SignalSocketFinalizer;
+      break;
     default:
       callback = NULL;
       UNREACHABLE();
diff --git a/runtime/bin/socket.h b/runtime/bin/socket.h
index 3d0cf31..a521e53 100644
--- a/runtime/bin/socket.h
+++ b/runtime/bin/socket.h
@@ -35,6 +35,15 @@
     kFinalizerNormal,
     kFinalizerListening,
     kFinalizerStdio,
+    kFinalizerSignal,
+  };
+
+  // Keep in sync with constants in _NativeSocket in socket_patch.dart.
+  enum SocketType {
+    kTcpSocket = 18,
+    kUdpSocket = 19,
+    kInternalSocket = 20,
+    kInternalSignalSocket = 21,
   };
 
   explicit Socket(intptr_t fd);
@@ -42,6 +51,8 @@
   intptr_t fd() const { return fd_; }
   void SetClosedFd();
 
+  Dart_Port isolate_port() const { return isolate_port_; }
+
   Dart_Port port() const { return port_; }
   void set_port(Dart_Port port) { port_ = port; }
 
@@ -84,6 +95,10 @@
     short_socket_write_ = short_socket_write;
   }
 
+  static bool IsSignalSocketFlag(intptr_t flag) {
+    return ((flag & (0x1 << kInternalSignalSocket)) != 0);
+  }
+
  private:
   ~Socket() {
     ASSERT(fd_ == kClosedFd);
@@ -97,6 +112,7 @@
   static bool short_socket_write_;
 
   intptr_t fd_;
+  Dart_Port isolate_port_;
   Dart_Port port_;
   uint8_t* udp_receive_buffer_;
 
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index 3a022b4..c3409ca 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -18,6 +18,7 @@
 Socket::Socket(intptr_t fd)
     : ReferenceCounted(),
       fd_(fd),
+      isolate_port_(Dart_GetMainPortId()),
       port_(ILLEGAL_PORT),
       udp_receive_buffer_(NULL) {}
 
diff --git a/runtime/bin/socket_fuchsia.cc b/runtime/bin/socket_fuchsia.cc
index 21932f0..8fb2d43 100644
--- a/runtime/bin/socket_fuchsia.cc
+++ b/runtime/bin/socket_fuchsia.cc
@@ -43,6 +43,7 @@
 Socket::Socket(intptr_t fd)
     : ReferenceCounted(),
       fd_(fd),
+      isolate_port_(Dart_GetMainPortId()),
       port_(ILLEGAL_PORT),
       udp_receive_buffer_(NULL) {}
 
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index 4a9d5e6..2d7f546 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -18,6 +18,7 @@
 Socket::Socket(intptr_t fd)
     : ReferenceCounted(),
       fd_(fd),
+      isolate_port_(Dart_GetMainPortId()),
       port_(ILLEGAL_PORT),
       udp_receive_buffer_(NULL) {}
 
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 3e1b704..e45c1a4 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -18,6 +18,7 @@
 Socket::Socket(intptr_t fd)
     : ReferenceCounted(),
       fd_(fd),
+      isolate_port_(Dart_GetMainPortId()),
       port_(ILLEGAL_PORT),
       udp_receive_buffer_(NULL) {}
 
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 6a74465..bf098c3 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -280,14 +280,19 @@
   static const int TYPE_TYPE_MASK = TYPE_LISTENING_SOCKET | PIPE_SOCKET;
 
   // Protocol flags.
+  // Keep in sync with SocketType enum in socket.h.
   static const int TCP_SOCKET = 18;
   static const int UDP_SOCKET = 19;
   static const int INTERNAL_SOCKET = 20;
+  static const int INTERNAL_SIGNAL_SOCKET = 21;
   static const int TYPE_TCP_SOCKET = 1 << TCP_SOCKET;
   static const int TYPE_UDP_SOCKET = 1 << UDP_SOCKET;
   static const int TYPE_INTERNAL_SOCKET = 1 << INTERNAL_SOCKET;
-  static const int TYPE_PROTOCOL_MASK =
-      TYPE_TCP_SOCKET | TYPE_UDP_SOCKET | TYPE_INTERNAL_SOCKET;
+  static const int TYPE_INTERNAL_SIGNAL_SOCKET = 1 << INTERNAL_SIGNAL_SOCKET;
+  static const int TYPE_PROTOCOL_MASK = TYPE_TCP_SOCKET |
+      TYPE_UDP_SOCKET |
+      TYPE_INTERNAL_SOCKET |
+      TYPE_INTERNAL_SIGNAL_SOCKET;
 
   // Native port messages.
   static const HOST_NAME_LOOKUP = 0;
@@ -581,15 +586,21 @@
 
   _NativeSocket.pipe() : typeFlags = TYPE_PIPE;
 
-  _NativeSocket.watch(int id)
-      : typeFlags = TYPE_NORMAL_SOCKET | TYPE_INTERNAL_SOCKET {
+  _NativeSocket._watchCommon(int id, int type)
+      : typeFlags = TYPE_NORMAL_SOCKET | type {
     isClosedWrite = true;
-    nativeSetSocketId(id);
+    nativeSetSocketId(id, typeFlags);
   }
 
+  _NativeSocket.watchSignal(int id)
+      : this._watchCommon(id, TYPE_INTERNAL_SIGNAL_SOCKET);
+
+  _NativeSocket.watch(int id) : this._watchCommon(id, TYPE_INTERNAL_SOCKET);
+
   bool get isListening => (typeFlags & TYPE_LISTENING_SOCKET) != 0;
   bool get isPipe => (typeFlags & TYPE_PIPE) != 0;
   bool get isInternal => (typeFlags & TYPE_INTERNAL_SOCKET) != 0;
+  bool get isInternalSignal => (typeFlags & TYPE_INTERNAL_SIGNAL_SOCKET) != 0;
   bool get isTcp => (typeFlags & TYPE_TCP_SOCKET) != 0;
   bool get isUdp => (typeFlags & TYPE_UDP_SOCKET) != 0;
 
@@ -612,13 +623,13 @@
     if (result != null) {
       available -= result.length;
       // TODO(ricow): Remove when we track internal and pipe uses.
-      assert(resourceInfo != null || isPipe || isInternal);
+      assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
       if (resourceInfo != null) {
         resourceInfo.totalRead += result.length;
       }
     }
     // TODO(ricow): Remove when we track internal and pipe uses.
-    assert(resourceInfo != null || isPipe || isInternal);
+    assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
     if (resourceInfo != null) {
       resourceInfo.didRead();
     }
@@ -639,13 +650,13 @@
       // emit read events.
       available = nativeAvailable();
       // TODO(ricow): Remove when we track internal and pipe uses.
-      assert(resourceInfo != null || isPipe || isInternal);
+      assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
       if (resourceInfo != null) {
         resourceInfo.totalRead += result.data.length;
       }
     }
     // TODO(ricow): Remove when we track internal and pipe uses.
-    assert(resourceInfo != null || isPipe || isInternal);
+    assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
     if (resourceInfo != null) {
       resourceInfo.didRead();
     }
@@ -689,7 +700,7 @@
     // Negate the result, as stated above.
     if (result < 0) result = -result;
     // TODO(ricow): Remove when we track internal and pipe uses.
-    assert(resourceInfo != null || isPipe || isInternal);
+    assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
     if (resourceInfo != null) {
       resourceInfo.addWrite(result);
     }
@@ -710,7 +721,7 @@
       result = 0;
     }
     // TODO(ricow): Remove when we track internal and pipe uses.
-    assert(resourceInfo != null || isPipe || isInternal);
+    assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
     if (resourceInfo != null) {
       resourceInfo.addWrite(result);
     }
@@ -730,7 +741,7 @@
     socket.localAddress = address;
     setupResourceInfo(socket);
     // TODO(ricow): Remove when we track internal and pipe uses.
-    assert(resourceInfo != null || isPipe || isInternal);
+    assert(resourceInfo != null || isPipe || isInternal || isInternalSignal);
     if (resourceInfo != null) {
       // We track this as read one byte.
       resourceInfo.addRead(1);
@@ -850,7 +861,8 @@
           assert(isClosing);
           assert(!isClosed);
           // TODO(ricow): Remove/update when we track internal and pipe uses.
-          assert(resourceInfo != null || isPipe || isInternal);
+          assert(
+              resourceInfo != null || isPipe || isInternal || isInternalSignal);
           if (resourceInfo != null) {
             _SocketResourceInfo.SocketClosed(resourceInfo);
           }
@@ -1084,7 +1096,7 @@
     if (result is OSError) throw result;
   }
 
-  void nativeSetSocketId(int id) native "Socket_SetSocketId";
+  void nativeSetSocketId(int id, int typeFlags) native "Socket_SetSocketId";
   nativeAvailable() native "Socket_Available";
   nativeRead(int len) native "Socket_Read";
   nativeRecvFrom() native "Socket_RecvFrom";
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index 2b979eb..1595aba 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -22,6 +22,7 @@
 Socket::Socket(intptr_t fd)
     : ReferenceCounted(),
       fd_(fd),
+      isolate_port_(Dart_GetMainPortId()),
       port_(ILLEGAL_PORT),
       udp_receive_buffer_(NULL) {
   ASSERT(fd_ != kClosedFd);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 65d32b9..57e024d 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -8,6 +8,7 @@
 get_retained_size_rpc_test: Pass, RuntimeError # Issue 28193
 isolate_lifecycle_test: Pass, RuntimeError # Issue 24174
 reload_sources_test: Pass, Slow # Reload is slow on the bots
+valid_source_locations_test: Pass, Slow # Generally slow, even in release-x64.
 
 [ $arch == arm ]
 process_service_test: Pass, Fail # Issue 24344
@@ -97,3 +98,4 @@
 # Skip all service tests because random reloads interfere.
 [ $hot_reload || $hot_reload_rollback ]
 *: SkipByDesign # The service tests should run without being reloaded.
+
diff --git a/runtime/observatory/tests/service/valid_source_locations_test.dart b/runtime/observatory/tests/service/valid_source_locations_test.dart
new file mode 100644
index 0000000..850f5fe
--- /dev/null
+++ b/runtime/observatory/tests/service/valid_source_locations_test.dart
@@ -0,0 +1,84 @@
+// Copyright (c) 2018, 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.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+import 'dart:async';
+import 'dart:developer';
+
+import 'package:observatory/service_io.dart';
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+void testFunction() {
+  debugger();
+}
+
+Future validateLocation(Location location) async {
+  if (location == null) return;
+  if (location.tokenPos < 0) return;
+
+  // Ensure the script is loaded.
+  final Script script = await location.script.load();
+
+  // Use the more low-level functions.
+  script.getLine(script.tokenToLine(location.tokenPos));
+  script.tokenToCol(location.tokenPos);
+
+  // Use the helper functions.
+  await location.getLine();
+  await location.getColumn();
+}
+
+Future validateFieldLocation(Field field) async {
+  // TODO(http://dartbug.com/32503): We should `field = await field.load()`
+  // here, but it causes all kinds of strong-mode errors.
+  await validateLocation(field.location);
+}
+
+Future validateFunctionLocation(ServiceFunction fun) async {
+  fun = await fun.load();
+  await validateLocation(fun.location);
+}
+
+Future validateClassLocation(Class klass) async {
+  klass = await klass.load();
+  await validateLocation(klass.location);
+
+  for (Field field in klass.fields) {
+    await validateFieldLocation(field);
+  }
+  for (ServiceFunction fun in klass.functions) {
+    await validateFunctionLocation(fun);
+  }
+}
+
+var tests = <IsolateTest>[
+  hasStoppedAtBreakpoint,
+  (Isolate isolate) async {
+    // Force everything to be compiled.
+    final params = {
+      'reports': ['Coverage'],
+      'forceCompile': true
+    };
+    await isolate.invokeRpcNoUpgrade('getSourceReport', params);
+
+    // Loop over all libraries, classes, functions and fields to ensure .
+    for (Library lib in isolate.libraries) {
+      lib = await lib.load();
+
+      for (Field field in lib.variables) {
+        await validateFieldLocation(field);
+      }
+      for (ServiceFunction fun in lib.functions) {
+        await validateFunctionLocation(fun);
+      }
+      for (Class klass in lib.classes) {
+        await validateClassLocation(klass);
+      }
+    }
+  },
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testFunction);
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 69d0ef0..983023c 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -256,13 +256,13 @@
 cc/IsolateReload_LibraryShow: Crash
 
 [ $compiler == dartk && $system == linux ]
-cc/IsolateReload_LibraryLookup: Crash
+cc/IsolateReload_LibraryLookup: Fail, Crash
 cc/IsolateReload_TearOff_AddArguments: Fail
 cc/IsolateReload_TearOff_Instance_Equality: Fail
 cc/IsolateReload_TearOff_List_Set: Fail
 
 [ $compiler == dartk && $system == windows ]
-cc/IsolateReload_LibraryLookup: Crash
+cc/IsolateReload_LibraryLookup: Fail, Crash
 cc/IsolateReload_TearOff_AddArguments: Fail
 cc/IsolateReload_TearOff_Instance_Equality: Fail
 cc/IsolateReload_TearOff_List_Set: Fail
@@ -284,7 +284,7 @@
 cc/FullSnapshot1: Crash # Issue 32190
 cc/IsolateReload_LibraryImportAdded: Crash # Issue 32190
 cc/IsolateReload_LibraryImportRemoved: Fail # Issue 32190
-cc/IsolateReload_LibraryLookup: Crash # Issue 32190
+cc/IsolateReload_LibraryLookup: Fail, Crash # Issue 32190
 cc/Mixin_PrivateSuperResolutionCrossLibraryShouldFail: Fail, Crash # Issue 32190
 cc/StackMapGC: Crash # Issue 32190
 
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 546542a..22f92eb 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -131,11 +131,17 @@
       canonical_name_ =
           builder_->ReadCanonicalNameReference();  // read canonical_name.
       if (++next_read_ == field) return;
+    case kSourceUriIndex:
+      source_uri_index_ = builder_->ReadUInt();  // read source_uri_index.
+      builder_->current_script_id_ = source_uri_index_;
+      if (++next_read_ == field) return;
     case kPosition:
       position_ = builder_->ReadPosition(false);  // read position.
+      builder_->record_token_position(position_);
       if (++next_read_ == field) return;
     case kEndPosition:
       end_position_ = builder_->ReadPosition(false);  // read end position.
+      builder_->record_token_position(end_position_);
       if (++next_read_ == field) return;
     case kFlags:
       flags_ = builder_->ReadFlags();
@@ -146,12 +152,6 @@
     case kName:
       builder_->SkipName();  // read name.
       if (++next_read_ == field) return;
-    case kSourceUriIndex:
-      source_uri_index_ = builder_->ReadUInt();  // read source_uri_index.
-      builder_->current_script_id_ = source_uri_index_;
-      builder_->record_token_position(position_);
-      builder_->record_token_position(end_position_);
-      if (++next_read_ == field) return;
     case kAnnotations: {
       annotation_count_ = builder_->ReadListLength();  // read list length.
       for (intptr_t i = 0; i < annotation_count_; ++i) {
@@ -200,11 +200,17 @@
       canonical_name_ =
           builder_->ReadCanonicalNameReference();  // read canonical_name.
       if (++next_read_ == field) return;
+    case kSourceUriIndex:
+      source_uri_index_ = builder_->ReadUInt();  // read source_uri_index.
+      builder_->current_script_id_ = source_uri_index_;
+      if (++next_read_ == field) return;
     case kPosition:
       position_ = builder_->ReadPosition(false);  // read position.
+      builder_->record_token_position(position_);
       if (++next_read_ == field) return;
     case kEndPosition:
       end_position_ = builder_->ReadPosition(false);  // read end position.
+      builder_->record_token_position(end_position_);
       if (++next_read_ == field) return;
     case kKind:
       kind_ = static_cast<Kind>(builder_->ReadByte());
@@ -215,12 +221,6 @@
     case kName:
       builder_->SkipName();  // read name.
       if (++next_read_ == field) return;
-    case kSourceUriIndex:
-      source_uri_index_ = builder_->ReadUInt();  // read source_uri_index.
-      builder_->current_script_id_ = source_uri_index_;
-      builder_->record_token_position(position_);
-      builder_->record_token_position(end_position_);
-      if (++next_read_ == field) return;
     case kAnnotations: {
       annotation_count_ = builder_->ReadListLength();  // read list length.
       for (intptr_t i = 0; i < annotation_count_; ++i) {
@@ -261,11 +261,17 @@
       canonical_name_ =
           builder_->ReadCanonicalNameReference();  // read canonical_name.
       if (++next_read_ == field) return;
+    case kSourceUriIndex:
+      source_uri_index_ = builder_->ReadUInt();  // read source_uri_index.
+      builder_->current_script_id_ = source_uri_index_;
+      if (++next_read_ == field) return;
     case kPosition:
       position_ = builder_->ReadPosition();  // read position.
+      builder_->record_token_position(position_);
       if (++next_read_ == field) return;
     case kEndPosition:
       end_position_ = builder_->ReadPosition();  // read end position.
+      builder_->record_token_position(end_position_);
       if (++next_read_ == field) return;
     case kFlags:
       flags_ = builder_->ReadFlags();
@@ -273,12 +279,6 @@
     case kName:
       builder_->SkipName();  // read name.
       if (++next_read_ == field) return;
-    case kSourceUriIndex:
-      source_uri_index_ = builder_->ReadUInt();  // read source_uri_index.
-      builder_->current_script_id_ = source_uri_index_;
-      builder_->record_token_position(position_);
-      builder_->record_token_position(end_position_);
-      if (++next_read_ == field) return;
     case kAnnotations: {
       annotation_count_ = builder_->ReadListLength();  // read list length.
       for (intptr_t i = 0; i < annotation_count_; ++i) {
@@ -316,11 +316,17 @@
       canonical_name_ =
           builder_->ReadCanonicalNameReference();  // read canonical_name.
       if (++next_read_ == field) return;
+    case kSourceUriIndex:
+      source_uri_index_ = builder_->ReadUInt();  // read source_uri_index.
+      builder_->current_script_id_ = source_uri_index_;
+      if (++next_read_ == field) return;
     case kPosition:
       position_ = builder_->ReadPosition(false);  // read position.
+      builder_->record_token_position(position_);
       if (++next_read_ == field) return;
     case kEndPosition:
       end_position_ = builder_->ReadPosition();  // read end position.
+      builder_->record_token_position(end_position_);
       if (++next_read_ == field) return;
     case kFlags:
       flags_ = builder_->ReadFlags();  // read flags.
@@ -328,11 +334,6 @@
     case kNameIndex:
       name_index_ = builder_->ReadStringReference();  // read name index.
       if (++next_read_ == field) return;
-    case kSourceUriIndex:
-      source_uri_index_ = builder_->ReadUInt();  // read source_uri_index.
-      builder_->current_script_id_ = source_uri_index_;
-      builder_->record_token_position(position_);
-      if (++next_read_ == field) return;
     case kAnnotations: {
       annotation_count_ = builder_->ReadListLength();  // read list length.
       for (intptr_t i = 0; i < annotation_count_; ++i) {
@@ -1599,7 +1600,27 @@
     }
     case kEmptyStatement:
       return;
-    case kAssertStatement: {
+    case kAssertBlock:
+      if (I->asserts()) {
+        PositionScope scope(builder_->reader_);
+        intptr_t offset =
+            builder_->ReaderOffset() - 1;  // -1 to include tag byte.
+
+        EnterScope(offset);
+
+        intptr_t list_length =
+            builder_->ReadListLength();  // read number of statements.
+        for (intptr_t i = 0; i < list_length; ++i) {
+          VisitStatement();  // read ith statement.
+        }
+
+        ExitScope(builder_->reader_->min_position(),
+                  builder_->reader_->max_position());
+      } else {
+        builder_->SkipStatementList();
+      }
+      return;
+    case kAssertStatement:
       if (I->asserts()) {
         VisitExpression();              // Read condition.
         builder_->ReadPosition();       // read condition start offset.
@@ -1618,7 +1639,6 @@
         }
       }
       return;
-    }
     case kLabeledStatement:
       VisitStatement();  // read body.
       return;
@@ -4946,6 +4966,8 @@
       return BuildBlock();
     case kEmptyStatement:
       return BuildEmptyStatement();
+    case kAssertBlock:
+      return BuildAssertBlock();
     case kAssertStatement:
       return BuildAssertStatement();
     case kLabeledStatement:
@@ -5193,6 +5215,13 @@
   SkipDartType();  // read return type.
 }
 
+void StreamingFlowGraphBuilder::SkipStatementList() {
+  intptr_t list_length = ReadListLength();  // read list length.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    SkipStatement();  // read ith expression.
+  }
+}
+
 void StreamingFlowGraphBuilder::SkipListOfExpressions() {
   intptr_t list_length = ReadListLength();  // read list length.
   for (intptr_t i = 0; i < list_length; ++i) {
@@ -5508,25 +5537,22 @@
     case kExpressionStatement:
       SkipExpression();  // read expression.
       return;
-    case kBlock: {
-      intptr_t list_length = ReadListLength();  // read number of statements.
-      for (intptr_t i = 0; i < list_length; ++i) {
-        SkipStatement();  // read ith statement.
-      }
+    case kBlock:
+      SkipStatementList();
       return;
-    }
     case kEmptyStatement:
       return;
-    case kAssertStatement: {
+    case kAssertBlock:
+      SkipStatementList();
+      return;
+    case kAssertStatement:
       SkipExpression();     // Read condition.
       ReadPosition();       // read condition start offset.
       ReadPosition();       // read condition end offset.
-      Tag tag = ReadTag();  // read (first part of) message.
-      if (tag == kSomething) {
+      if (ReadTag() == kSomething) {
         SkipExpression();  // read (rest of) message.
       }
       return;
-    }
     case kLabeledStatement:
       SkipStatement();  // read body.
       return;
@@ -5692,15 +5718,15 @@
 }
 
 void StreamingFlowGraphBuilder::SkipLibraryPart() {
-  SkipListOfExpressions();  // Read annotations.
   ReadUInt();               // Read source_uri_index.
+  SkipListOfExpressions();  // Read annotations.
 }
 
 void StreamingFlowGraphBuilder::SkipLibraryTypedef() {
   SkipCanonicalNameReference();  // read canonical name.
+  ReadUInt();                    // read source_uri_index.
   ReadPosition();                // read position.
   SkipStringReference();         // read name index.
-  ReadUInt();                    // read source_uri_index.
   SkipListOfExpressions();       // read annotations.
   SkipTypeParametersList();      // read type parameters.
   SkipDartType();                // read type.
@@ -8230,6 +8256,30 @@
   return Fragment();
 }
 
+Fragment StreamingFlowGraphBuilder::BuildAssertBlock() {
+  if (!I->asserts()) {
+    SkipStatementList();
+    return Fragment();
+  }
+
+  intptr_t offset = ReaderOffset() - 1;  // Include the tag.
+
+  Fragment instructions;
+
+  instructions += EnterScope(offset);
+  intptr_t list_length = ReadListLength();  // read number of statements.
+  for (intptr_t i = 0; i < list_length; ++i) {
+    if (instructions.is_open()) {
+      instructions += BuildStatement();  // read ith statement.
+    } else {
+      SkipStatement();  // read ith statement.
+    }
+  }
+  instructions += ExitScope(offset);
+
+  return instructions;
+}
+
 Fragment StreamingFlowGraphBuilder::BuildAssertStatement() {
   if (!I->asserts()) {
     SetOffset(ReaderOffset() - 1);  // Include the tag.
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 1b7c927..40d1d89 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -158,12 +158,12 @@
   enum Field {
     kStart,  // tag.
     kCanonicalName,
+    kSourceUriIndex,
     kPosition,
     kEndPosition,
     kFlags,
     kFlags2,
     kName,
-    kSourceUriIndex,
     kAnnotations,
     kType,
     kInitializer,
@@ -244,12 +244,12 @@
   enum Field {
     kStart,  // tag.
     kCanonicalName,
+    kSourceUriIndex,
     kPosition,
     kEndPosition,
     kKind,
     kFlags,
     kName,
-    kSourceUriIndex,
     kAnnotations,
     kForwardingStubSuperTarget,
     kForwardingStubInterfaceTarget,
@@ -327,11 +327,11 @@
   enum Field {
     kStart,  // tag.
     kCanonicalName,
+    kSourceUriIndex,
     kPosition,
     kEndPosition,
     kFlags,
     kName,
-    kSourceUriIndex,
     kAnnotations,
     kFunction,
     kInitializers,
@@ -386,11 +386,11 @@
   enum Field {
     kStart,  // tag.
     kCanonicalName,
+    kSourceUriIndex,
     kPosition,
     kEndPosition,
     kFlags,
     kNameIndex,
-    kSourceUriIndex,
     kAnnotations,
     kTypeParameters,
     kSuperClass,
@@ -1101,6 +1101,7 @@
   void SkipOptionalDartType();
   void SkipInterfaceType(bool simple);
   void SkipFunctionType(bool simple);
+  void SkipStatementList();
   void SkipListOfExpressions();
   void SkipListOfDartTypes();
   void SkipListOfStrings();
@@ -1347,6 +1348,7 @@
   Fragment BuildExpressionStatement();
   Fragment BuildBlock();
   Fragment BuildEmptyStatement();
+  Fragment BuildAssertBlock();
   Fragment BuildAssertStatement();
   Fragment BuildLabeledStatement();
   Fragment BuildBreakStatement();
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index 3c56a69..8f67d03 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -104,6 +104,7 @@
   V(VariableDeclaration, 78)                                                   \
   V(FunctionDeclaration, 79)                                                   \
   V(AsyncForInStatement, 80)                                                   \
+  V(AssertBlock, 81)                                                           \
   V(TypedefType, 87)                                                           \
   V(VectorType, 88)                                                            \
   V(BottomType, 89)                                                            \
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index c95abf0..fa60ee8 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -662,7 +662,7 @@
     builder_.SetOffset(kernel_offset);
     LibraryHelper library_helper(&builder_);
     library_helper.ReadUntilIncluding(LibraryHelper::kCanonicalName);
-    dart::Library& lib = LookupLibrary(library_helper.canonical_name_);
+    dart::Library& lib = LookupLibraryOrNull(library_helper.canonical_name_);
     if (!lib.IsNull() && !lib.is_dart_scheme()) {
       // This is a library that already exists so mark it as being modified.
       modified_libs->Add(lib.index());
@@ -983,9 +983,29 @@
 // dart:-scheme libraries to look like they looked like in legacy pipeline:
 //
 //               dart:libname/filename.dart
+//               dart:libname/runtime/lib/filename.dart
+//               dart:libname/runtime/bin/filename.dart
 //
 void KernelLoader::FixCoreLibraryScriptUri(const Library& library,
                                            const Script& script) {
+  struct Helper {
+    static bool EndsWithCString(const String& haystack,
+                                const char* needle,
+                                intptr_t needle_length,
+                                intptr_t end_pos) {
+      const intptr_t start = end_pos - needle_length + 1;
+      if (start >= 0) {
+        for (intptr_t i = 0; i < needle_length; i++) {
+          if (haystack.CharAt(start + i) != needle[i]) {
+            return false;
+          }
+        }
+        return true;
+      }
+      return false;
+    }
+  };
+
   if (library.is_dart_scheme()) {
     String& url = String::Handle(zone_, script.url());
     if (!url.StartsWith(Symbols::DartScheme())) {
@@ -997,9 +1017,28 @@
         pos--;
       }
 
+      static const char* kRuntimeLib = "runtime/lib/";
+      static const intptr_t kRuntimeLibLen = strlen(kRuntimeLib);
+      const bool inside_runtime_lib =
+          Helper::EndsWithCString(url, kRuntimeLib, kRuntimeLibLen, pos);
+
+      static const char* kRuntimeBin = "runtime/bin/";
+      static const intptr_t kRuntimeBinLen = strlen(kRuntimeBin);
+      const bool inside_runtime_bin =
+          Helper::EndsWithCString(url, kRuntimeBin, kRuntimeBinLen, pos);
+
+      String& tmp = String::Handle(zone_);
       url = String::SubString(url, pos + 1);
+      if (inside_runtime_lib) {
+        tmp = String::New("runtime/lib", Heap::kNew);
+        url = String::Concat(tmp, url);
+      } else if (inside_runtime_bin) {
+        tmp = String::New("runtime/bin", Heap::kNew);
+        url = String::Concat(tmp, url);
+      }
+      tmp = library.url();
       url = String::Concat(Symbols::Slash(), url);
-      url = String::Concat(String::Handle(zone_, library.url()), url);
+      url = String::Concat(tmp, url);
       script.set_url(url);
     }
   }
@@ -1017,9 +1056,6 @@
   Class& klass = LookupClass(class_helper.canonical_name_);
   klass.set_kernel_offset(class_offset - correction_offset_);
 
-  class_helper.ReadUntilIncluding(ClassHelper::kFlags);
-  if (class_helper.is_enum_class()) klass.set_is_enum_class();
-
   // The class needs to have a script because all the functions in the class
   // will inherit it.  The predicate Function::IsOptimizable uses the absence of
   // a script to detect test functions that should not be optimized.
@@ -1035,6 +1071,9 @@
     klass.set_token_pos(class_helper.position_);
   }
 
+  class_helper.ReadUntilIncluding(ClassHelper::kFlags);
+  if (class_helper.is_enum_class()) klass.set_is_enum_class();
+
   class_helper.ReadUntilIncluding(ClassHelper::kAnnotations);
   class_helper.ReadUntilExcluding(ClassHelper::kTypeParameters);
   intptr_t type_parameter_counts =
@@ -1088,16 +1127,18 @@
       intptr_t field_offset = builder_.ReaderOffset() - correction_offset_;
       ActiveMemberScope active_member(&active_class_, NULL);
       FieldHelper field_helper(&builder_);
-      field_helper.ReadUntilExcluding(FieldHelper::kName);
 
+      field_helper.ReadUntilIncluding(FieldHelper::kSourceUriIndex);
+      const Object& script_class =
+          ClassForScriptAt(klass, field_helper.source_uri_index_);
+
+      field_helper.ReadUntilExcluding(FieldHelper::kName);
       const String& name = builder_.ReadNameAsFieldName();
       field_helper.SetJustRead(FieldHelper::kName);
       field_helper.ReadUntilExcluding(FieldHelper::kType);
       const AbstractType& type =
           T.BuildTypeWithoutFinalization();  // read type.
       field_helper.SetJustRead(FieldHelper::kType);
-      const Object& script_class =
-          ClassForScriptAt(klass, field_helper.source_uri_index_);
 
       const bool is_reflectable =
           field_helper.position_.IsReal() &&
@@ -1153,6 +1194,16 @@
 
     const String& name =
         H.DartConstructorName(constructor_helper.canonical_name_);
+
+    // We can have synthetic constructors, which will not have a source uri
+    // attached to them (which means the index into the source uri table is 0,
+    // see `package:kernel/binary/ast_to_binary::writeUriReference`.
+    const Object* owner = &klass;
+    const intptr_t source_uri_index = constructor_helper.source_uri_index_;
+    if (source_uri_index != 0) {
+      owner = &ClassForScriptAt(klass, source_uri_index);
+    }
+
     Function& function = Function::ZoneHandle(
         Z, Function::New(name, RawFunction::kConstructor,
                          false,  // is_static
@@ -1160,7 +1211,7 @@
                          false,  // is_abstract
                          constructor_helper.IsExternal(),
                          false,  // is_native
-                         klass, constructor_helper.position_));
+                         *owner, constructor_helper.position_));
     function.set_end_token_pos(constructor_helper.end_position_);
     functions_.Add(&function);
     function.set_kernel_offset(constructor_offset);
@@ -1553,6 +1604,18 @@
   }
 }
 
+Library& KernelLoader::LookupLibraryOrNull(NameIndex library) {
+  Library* handle = NULL;
+  if (!libraries_.Lookup(library, &handle)) {
+    const String& url = H.DartString(H.CanonicalNameString(library));
+    handle = &Library::Handle(Z, Library::LookupLibrary(thread_, url));
+    if (!handle->IsNull()) {
+      libraries_.Insert(library, handle);
+    }
+  }
+  return *handle;
+}
+
 Library& KernelLoader::LookupLibrary(NameIndex library) {
   Library* handle = NULL;
   if (!libraries_.Lookup(library, &handle)) {
diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h
index c66d499..7cafb9d 100644
--- a/runtime/vm/kernel_loader.h
+++ b/runtime/vm/kernel_loader.h
@@ -234,6 +234,7 @@
 
   void LoadLibraryImportsAndExports(Library* library);
 
+  Library& LookupLibraryOrNull(NameIndex library);
   Library& LookupLibrary(NameIndex library);
   Class& LookupClass(NameIndex klass);
 
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index 17bde46..c490d36 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -27,7 +27,7 @@
  *                                0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
  */
 const Utf8Codec utf8 = const Utf8Codec();
-@Deprecated("Use Utf8Codec instead")
+@Deprecated("Use utf8 instead")
 const Utf8Codec UTF8 = utf8;
 
 /**
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 9944d46..86b9d35 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -3,7 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError # compiler cancelled: cannot resolve type T
 Language/Classes/Constructors/Generative_Constructors/execution_of_a_superinitializer_t01: RuntimeError, OK # co19 issue 258
 Language/Expressions/Assignment/super_assignment_failed_t05: RuntimeError # Issue 25671
 Language/Expressions/Assignment/super_assignment_value_t02: RuntimeError # Please triage this failure
@@ -73,6 +72,8 @@
 Language/Types/Type_Void/syntax_t05: MissingCompileTimeError, Crash
 Language/Types/Type_Void/syntax_t08: MissingCompileTimeError
 LayoutTests/fast/css/content/content-quotes-01_t01: Pass, RuntimeError
+LayoutTests/fast/css/font-face-cache-bug_t01: Pass, RuntimeError
+LayoutTests/fast/css/fontfaceset-loadingdone_t01: Pass, RuntimeError
 LayoutTests/fast/dom/HTMLLinkElement/link-onload-stylesheet-with-import_t01: Skip # https://github.com/dart-lang/sdk/issues/28873
 LayoutTests/fast/dom/css-innerHTML_t01: SkipByDesign # Test is incorrect.
 LayoutTests/fast/dom/mutation-event-remove-inserted-node_t01: Skip # https://github.com/dart-lang/sdk/issues/28873
@@ -611,7 +612,6 @@
 LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/icon-size-property_t01: Skip # Roll 50 failure
-LayoutTests/fast/dom/icon-size-property_t01: RuntimeError # https://github.com/dart-lang/sdk/issues/26422
 LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # API not supported.
 LayoutTests/fast/dom/navigatorcontentutils/register-protocol-handler_t01: Skip # API not supported.
@@ -1160,7 +1160,6 @@
 WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-005_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/events/event-dispatch/test-002_t01: RuntimeError # Please triage this failure.
-WebPlatformTest/shadow-dom/events/event-dispatch/test-003_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/events/event-dispatch/test-003_t01: Skip # Times out
 WebPlatformTest/shadow-dom/events/event-retargeting/test-001_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: RuntimeError # Please triage this failure
@@ -1445,6 +1444,12 @@
 [ $compiler == dart2js && $runtime == d8 && $system == windows ]
 LibTest/async/DeferredLibrary/*: Skip # Issue 17458
 
+[ $compiler == dart2js && $runtime == d8 && $checked && $fast_startup && $minified ]
+Language/Classes/Constructors/Factories/function_type_t02: RuntimeError
+Language/Expressions/Instance_Creation/New/redirecting_factory_constructor_t02: RuntimeError
+Language/Generics/malformed_t02: Crash
+LibTest/async/DeferredLibrary/DeferredLibrary_A01_t01: RuntimeError
+
 [ $compiler == dart2js && $runtime == d8 && $fast_startup ]
 LibTest/isolate/Isolate/spawn_A04_t04: Fail # Issue 27558
 
@@ -1491,17 +1496,12 @@
 LayoutTests/fast/canvas/canvas-putImageData_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/crash-set-font_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/buffer-bind-test_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/buffer-bind-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/buffer-data-array-buffer_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/canvas-2d-webgl-texture_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/canvas-2d-webgl-texture_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/canvas-test_t01: Pass, RuntimeError # Issue 29634
@@ -1522,64 +1522,36 @@
 LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/framebuffer-test_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/functions-returning-strings_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/functions-returning-strings_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/get-active-test_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/get-active-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-enable-enum-test_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/gl-enum-tests_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/gl-enum-tests_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-get-calls_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/gl-get-calls_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/gl-getstring_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-getstring_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/gl-pixelstorei_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-pixelstorei_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-teximage_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/gl-uniformmatrix4fv_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-uniformmatrix4fv_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/gl-vertex-attrib-zero-issues_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/gl-vertex-attrib_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-vertex-attrib_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/gl-vertexattribpointer_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-vertexattribpointer_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/glsl-conformance_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/glsl-conformance_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/index-validation-copies-indices_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/index-validation-copies-indices_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/index-validation-crash-with-buffer-sub-data_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/index-validation-crash-with-buffer-sub-data_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/index-validation-verifies-too-many-indices_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/index-validation-verifies-too-many-indices_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/index-validation-with-resized-buffer_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/index-validation-with-resized-buffer_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/index-validation_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/index-validation_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/invalid-UTF-16_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/invalid-UTF-16_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/is-object_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/is-object_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/null-uniform-location_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/null-uniform-location_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/canvas/webgl/point-size_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/point-size_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: Pass, RuntimeError # Issue 29634
 LayoutTests/fast/canvas/webgl/program-test_t01: Pass, RuntimeError # Issue 29634
@@ -1735,7 +1707,6 @@
 LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLSelectElement/remove-element-from-within-focus-handler-crash_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLSelectElement/selected-index-preserved-when-option-text-changes_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/dom/HTMLSelectElement/selected-index-preserved-when-option-text-changes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLTemplateElement/custom-element-wrapper-gc_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLTemplateElement/innerHTML_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLTemplateElement/ownerDocumentXHTML_t01: RuntimeError # Please triage this failure
@@ -1760,7 +1731,6 @@
 LayoutTests/fast/dom/Window/window-resize-contents_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/anchor-without-content_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # Please triage this failure
@@ -1791,7 +1761,6 @@
 LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-optgroup_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dynamic/ancestor-to-absolute_t01: Pass, RuntimeError # Issue 29634
-LayoutTests/fast/dynamic/ancestor-to-absolute_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/events/add-event-without-document_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Skip # Times out.
 LayoutTests/fast/events/document-elementFromPoint_t01: RuntimeError # Please triage this failure
@@ -2109,10 +2078,8 @@
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out.
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: Pass, RuntimeError # Issue 29634
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError, Pass # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: Pass, RuntimeError # Issue 29634
-WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-button-element/button-validation_t01: RuntimeError # Please triage this failure
@@ -2134,7 +2101,6 @@
 WebPlatformTest/html/semantics/forms/the-input-element/time_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-input-element/time_t02: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-input-element/type-change-state_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/forms/the-input-element/url_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-input-element/url_t01: Pass, RuntimeError # Issue 29634
 WebPlatformTest/html/semantics/forms/the-input-element/valueMode_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-input-element/week_t01: RuntimeError # Please triage this failure
@@ -2153,7 +2119,6 @@
 WebPlatformTest/html/semantics/selectors/pseudo-classes/inrange-outofrange_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/tabular-data/the-tr-element/rowIndex_t01: Pass, RuntimeError # Issue 29634
-WebPlatformTest/html/semantics/tabular-data/the-tr-element/rowIndex_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t02: RuntimeError # Please triage this failure
 WebPlatformTest/html/syntax/serializing-html-fragments/outerHTML_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: RuntimeError # Please triage this failure
@@ -5602,13 +5567,10 @@
 LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: Fail # co19-roll r587: Please triage this failure
 LibTest/typed_data/Float64List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int16List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int16List/toList_A01_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int32List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
-LibTest/typed_data/Int32List/toList_A01_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Int32x4/operator_OR_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/typed_data/Int8List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint16List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
-LibTest/typed_data/Uint16List/toList_A01_t01: Fail # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint32List/toList_A01_t01: Skip # issue 16934, co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint8ClampedList/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
 LibTest/typed_data/Uint8List/toList_A01_t01: Skip # co19-roll r559: Please triage this failure
@@ -5775,7 +5737,6 @@
 LayoutTests/fast/css/dynamic-class-backdrop-pseudo_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/focus-display-block-inline_t01: Pass, RuntimeError # Fails 5 out of 10.
-LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-cache-bug_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-unicode-range-load_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-unicode-range-monospace_t01: RuntimeError # Please triage this failure
@@ -5822,7 +5783,6 @@
 LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/parsing-unexpected-eof_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/pseudo-any_t01: Pass, RuntimeError # Fails 4 out of 10.
-LayoutTests/fast/css/pseudo-any_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/css/readonly-pseudoclass-opera-001_t01: RuntimeError # Please triage this failure
@@ -6147,12 +6107,10 @@
 LayoutTests/fast/filesystem/simple-temporary_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/filesystem/snapshot-file-with-gc_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/flexbox/repaint-scrollbar_t01: Pass, RuntimeError # Fails 2 out of 10.
-LayoutTests/fast/flexbox/repaint-scrollbar_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/ValidityState-customError_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/ValidityState-typeMismatch-email_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/autocomplete_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Pass, RuntimeError # Fails 7 out of 10.
-LayoutTests/fast/forms/autofocus-input-css-style-change_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/button-baseline-and-collapsing_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/button/button-disabled-blur_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/clone-input-with-dirty-value_t01: RuntimeError # Please triage this failure
@@ -6163,7 +6121,6 @@
 LayoutTests/fast/forms/datalist/input-list_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-change-layout-by-value_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # Fails 6 out of 10.
-LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/date/ValidityState-rangeOverflow-date_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/date/ValidityState-rangeUnderflow-date_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/date/ValidityState-stepMismatch-date_t01: RuntimeError # Please triage this failure
@@ -6768,6 +6725,12 @@
 WebPlatformTest/webstorage/event_session_storagearea_t01: Pass, RuntimeError # Fails on 7.1. Please triage this failure
 WebPlatformTest/webstorage/event_session_url_t01: Skip # Times out. Please triage this failure
 
+[ $compiler == dart2js && $runtime == safari && $fasta ]
+Language/Expressions/Await_Expressions/evaluation_throws_t05: RuntimeError
+Language/Expressions/Method_Invocation/Ordinary_Invocation/method_lookup_failed_t19: RuntimeError
+Language/Libraries_and_Scripts/Exports/syntax_t02: RuntimeError
+Language/Libraries_and_Scripts/Imports/syntax_t37: RuntimeError
+
 [ $compiler == dart2js && $browser ]
 LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/dom/HTMLButtonElement/change-type_t01: Skip # Test reloads itself. Issue 18558.
@@ -6832,7 +6795,6 @@
 LayoutTests/fast/table/margins-flipped-text-direction_t01: Pass, RuntimeError # Issue 747
 LayoutTests/fast/table/min-max-width-preferred-size_t01: Pass, RuntimeError # Issue 747
 LayoutTests/fast/table/table-width-exceeding-max-width_t01: Pass, RuntimeError # Issue 747
-LayoutTests/fast/text/font-fallback-synthetic-italics_t01: RuntimeError # Issue 747
 LayoutTests/fast/text/font-fallback-synthetic-italics_t01: Pass, RuntimeError # Issue 747
 LayoutTests/fast/text/font-ligatures-linebreak-word_t01: Skip # Issue 747
 LayoutTests/fast/text/font-ligatures-linebreak_t01: Skip # Issue 747
@@ -7087,8 +7049,8 @@
 Language/Mixins/Mixin_Application/syntax_t25: RuntimeError
 Language/Statements/Continue/async_loops_t10: Timeout
 Language/Types/Type_Void/syntax_t09: MissingCompileTimeError
-LayoutTests/fast/canvas/gradient-addColorStop-with-invalid-color_t01: RuntimeError
-LayoutTests/fast/canvas/rgba-parsing_t01: RuntimeError
+LayoutTests/fast/canvas/gradient-addColorStop-with-invalid-color_t01: Pass, RuntimeError
+LayoutTests/fast/canvas/rgba-parsing_t01: Pass, RuntimeError
 LibTest/core/Invocation/namedArguments_A01_t01: RuntimeError
 LibTest/html/Document/dispatchEvent_A01_t01: Crash
 LibTest/html/Document/on_A01_t01: Crash
@@ -7116,6 +7078,8 @@
 LibTest/html/Node/dispatchEvent_A01_t01: Crash
 LibTest/html/Window/dispatchEvent_A01_t01: Crash
 LibTest/html/Window/postMessage_A01_t02: Crash
+LibTest/html/Window/requestFileSystem_A01_t01: Crash
+LibTest/html/Window/requestFileSystem_A01_t02: Crash
 LibTest/html/Window/requestFileSystem_A02_t01: Crash
 LibTest/isolate/SendPort/send_A01_t03: RuntimeError
 WebPlatformTest/html/semantics/embedded-content/the-audio-element/audio_constructor_t01: RuntimeError
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index a66ff5b..8e7ae4b 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -991,8 +991,6 @@
 Language/Statements/For/For_Loop/execution_t07: CompileTimeError
 Language/Statements/For/For_Loop/execution_t08: CompileTimeError
 Language/Statements/For/syntax_t07: CompileTimeError
-Language/Statements/For/syntax_t12: MissingCompileTimeError
-Language/Statements/For/syntax_t19: MissingCompileTimeError
 Language/Statements/If/condition_evaluation_t01: CompileTimeError
 Language/Statements/If/condition_evaluation_t02: CompileTimeError
 Language/Statements/If/type_t06: CompileTimeError
@@ -1714,10 +1712,6 @@
 Language/Mixins/declaring_constructor_t05: MissingCompileTimeError
 Language/Mixins/declaring_constructor_t06: MissingCompileTimeError
 Language/Statements/Continue/label_t07: MissingCompileTimeError
-Language/Statements/For/syntax_t12: MissingCompileTimeError
-Language/Statements/For/syntax_t13: MissingCompileTimeError
-Language/Statements/For/syntax_t19: MissingCompileTimeError
-Language/Statements/For/syntax_t20: MissingCompileTimeError
 Language/Statements/Switch/equal_operator_t01: MissingCompileTimeError
 Language/Statements/Switch/equal_operator_t02: MissingCompileTimeError
 Language/Statements/Switch/expressions_t01: MissingCompileTimeError
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 5eb6348..7a80c04 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -264,8 +264,6 @@
 Language/Statements/Continue/label_t10: MissingCompileTimeError
 Language/Statements/Continue/label_t11: MissingCompileTimeError
 Language/Statements/Do/condition_type_t02: MissingCompileTimeError
-Language/Statements/For/syntax_t12: MissingCompileTimeError
-Language/Statements/For/syntax_t19: MissingCompileTimeError
 Language/Statements/Labels/scope_t05: MissingCompileTimeError
 Language/Statements/Switch/equal_operator_t01: MissingCompileTimeError
 Language/Statements/Switch/equal_operator_t02: MissingCompileTimeError
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 6fd332e..31320ad 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -29,7 +29,9 @@
 mirrors/library_imports_prefixed_show_hide_test: Fail # Issue 32057
 mirrors/library_imports_prefixed_test: Fail
 mirrors/library_imports_shown_test: Fail
+model/subtype_test: Pass, Slow
 no_such_method_enabled_test: Pass, Slow
+old_frontend/bad_loop_test: RuntimeError
 old_frontend/check_elements_invariants_test: Skip # Times out even with Slow marker. Slow due to inlining in the CPS backend
 old_frontend/compile_with_empty_libraries_test: Fail # Issue 24223
 old_frontend/patch_test/bug: RuntimeError # Issue 21132
diff --git a/tests/compiler/dart2js/dill_loader_test.dart b/tests/compiler/dart2js/dill_loader_test.dart
index 56ac318..1963d3b 100644
--- a/tests/compiler/dart2js/dill_loader_test.dart
+++ b/tests/compiler/dart2js/dill_loader_test.dart
@@ -15,7 +15,7 @@
 import 'package:compiler/src/apiimpl.dart' show CompilerImpl;
 import "package:expect/expect.dart";
 import 'package:front_end/src/api_prototype/front_end.dart';
-import 'package:front_end/src/fasta/kernel/utils.dart' show serializeProgram;
+import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;
 import 'package:compiler/src/kernel/dart2js_target.dart';
 import 'package:kernel/target/targets.dart' show TargetFlags;
 import 'package:front_end/src/compute_platform_binaries_location.dart'
@@ -52,7 +52,7 @@
       ..verify = true;
 
     List<int> kernelBinary =
-        serializeProgram(await kernelForProgram(uri, options));
+        serializeComponent(await kernelForProgram(uri, options));
     CompilerImpl compiler = compilerFor(
         entryPoint: entryPoint,
         memorySourceFiles: {'main.dill': kernelBinary},
diff --git a/tests/compiler/dart2js/kernel/compiler_helper.dart b/tests/compiler/dart2js/kernel/compiler_helper.dart
index a11907e..e32bb06 100644
--- a/tests/compiler/dart2js/kernel/compiler_helper.dart
+++ b/tests/compiler/dart2js/kernel/compiler_helper.dart
@@ -61,15 +61,15 @@
 }
 
 class MemoryKernelLibraryLoaderTask extends KernelLibraryLoaderTask {
-  final ir.Program program;
+  final ir.Component component;
 
   MemoryKernelLibraryLoaderTask(KernelToElementMapForImpact elementMap,
-      DiagnosticReporter reporter, Measurer measurer, this.program)
+      DiagnosticReporter reporter, Measurer measurer, this.component)
       : super(null, null, elementMap, null, reporter, measurer);
 
   Future<LoadedLibraries> loadLibrary(Uri resolvedUri,
       {bool skipFileWithPartOfTag: false}) async {
-    return createLoadedLibraries(program);
+    return createLoadedLibraries(component);
   }
 }
 
diff --git a/tests/html/html.status b/tests/html/html.status
index bd9c707..3796ec1 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -485,9 +485,6 @@
 mirrors_js_typed_interop_test: SkipByDesign
 postmessage_structured_test: SkipByDesign
 
-[ $compiler == dart2js && !$csp && $fast_startup && $fasta ]
-websql_test/Database/Database: RuntimeError
-
 [ $compiler == dart2js && $fast_startup ]
 custom/mirrors_2_test: Fail # mirrors not supported
 custom/mirrors_test: Fail # mirrors not supported
@@ -504,6 +501,7 @@
 js_typed_interop_default_arg_test/explicit_argument: RuntimeError
 js_typed_interop_test/static_method_tearoff_1: RuntimeError
 mirrors_js_typed_interop_test: SkipByDesign
+websql_test/Database/Database: Pass, RuntimeError
 
 [ $compiler == dart2js && $fasta && $host_checked ]
 fontface_loaded_test: Crash
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 1727004..d22d01b 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -86,13 +86,6 @@
 cross_isolate_message_test: Skip # Issue 12627
 message_test: Skip # Issue 12627
 
-[ $compiler == dart2js && $browser && !$csp && $fast_startup && $fasta ]
-browser/package_resolve_browser_hook2_test: RuntimeError
-browser/package_resolve_browser_test: RuntimeError
-
-[ $compiler == dart2js && $browser && $fast_startup && $fasta ]
-browser/package_resolve_browser_hook_test: RuntimeError
-
 [ $compiler == dart2js && !$browser && $fast_startup ]
 isolate_current_test: Fail # please triage
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index b2a238a..5161156 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -16,15 +16,15 @@
 [ $arch == ia32 && $compiler == dart2js && $runtime == d8 ]
 new_expression2_negative_test: Pass, Crash # Flaky, issue 31131
 
+[ $builder_tag == win7 && $compiler == dart2js && $fasta ]
+deep_nesting2_negative_test: Crash
+illegal_declaration_test/01: Crash
+issue1578_negative_test: Crash
+regress_23051_test/01: Crash
+
 [ $compiler == dart2js && $runtime == chrome && $system == macos ]
 await_future_test: Pass, Timeout # Issue 26735
 
-[ $compiler == dart2js && $runtime == chrome && $fasta ]
-conditional_import_string_test: RuntimeError
-conditional_import_test: RuntimeError
-config_import_corelib_test: RuntimeError
-library_env_test/has_io_support: RuntimeError
-
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 override_field_test/02: Pass, Slow # TODO(kasperl): Please triage.
 
@@ -38,12 +38,6 @@
 [ $compiler == dart2js && $runtime == ff ]
 round_test: Pass, Fail, OK # Fixed in ff 35. Common JavaScript engine Math.round bug.
 
-[ $compiler == dart2js && $runtime == ff && $fasta ]
-conditional_import_string_test: RuntimeError
-conditional_import_test: RuntimeError
-config_import_corelib_test: RuntimeError
-library_env_test/has_io_support: RuntimeError
-
 [ $compiler == dart2js && $runtime != ff && $fasta ]
 stacktrace_test: RuntimeError # Issue 12698
 
@@ -63,17 +57,24 @@
 [ $compiler == dart2js && $runtime == safari ]
 round_test: Fail, OK # Common JavaScript engine Math.round bug.
 
-[ $compiler == dart2js && $system == windows && ($runtime == chrome || $runtime == ff) ]
+[ $compiler == dart2js && $runtime == safari && $fasta ]
+call_nonexistent_constructor_test/02: RuntimeError
+named_parameters2_test: RuntimeError
+named_parameters3_test: RuntimeError
+named_parameters4_test: RuntimeError
+
+[ $compiler == dart2js && $system == windows && !$fasta && ($runtime == chrome || $runtime == ff) ]
 string_literals_test: RuntimeError # Issue 27533
 
 [ $compiler == dart2js && $browser && $csp && !$fast_startup ]
 conditional_import_string_test: Fail # Issue 30615
 conditional_import_test: Fail # Issue 30615
 
-[ $compiler == dart2js && $browser && !$csp && $fast_startup && $fasta ]
-async_await_test: RuntimeError
-async_star_pause_test: RuntimeError
-async_star_test: RuntimeError
+[ $compiler == dart2js && $browser && $fasta ]
+conditional_import_string_test: RuntimeError
+conditional_import_test: RuntimeError
+config_import_corelib_test: RuntimeError
+library_env_test/has_io_support: RuntimeError
 
 [ $compiler == dart2js && $browser && !$fasta ]
 config_import_test: Fail # Test flag is not passed to the compiler.
diff --git a/tests/language_2/issue28498_test.dart b/tests/language_2/issue28498_test.dart
new file mode 100644
index 0000000..664d33b
--- /dev/null
+++ b/tests/language_2/issue28498_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2018, 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.
+
+// The Kernel async transformer should not skip assert statements.
+
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+g() async => 21;
+f() async => 42;
+
+test() async {
+  assert(await g() == await f());
+}
+
+main() {
+  bool ok = true;
+  assert(!(ok = false));
+  // !ok iff asserts are enabled.
+
+  asyncStart();
+  test().then((_) => Expect.isTrue(ok), onError: (error) {
+    // !ok implies error is AssertionError.
+    Expect.isTrue(ok || error is AssertionError);
+  }).whenComplete(asyncEnd);
+}
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index e031eda..db6dba1 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -2390,6 +2390,7 @@
 issue18628_2_test/01: MissingCompileTimeError
 issue21079_test: RuntimeError
 issue23244_test: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
+issue28498_test: Crash
 issue31596_override_test/07: MissingCompileTimeError
 issue31596_override_test/08: MissingCompileTimeError
 issue31596_super_test/01: CompileTimeError
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 83ebc63..cea3c5c 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -694,8 +694,6 @@
 local_function2_test/none: RuntimeError
 local_function3_test/none: RuntimeError
 local_function_test/none: RuntimeError
-main_not_a_function_test: Skip
-main_not_a_function_test: DartkCrash
 main_test/03: RuntimeError
 map_literal3_test/01: MissingCompileTimeError
 map_literal3_test/02: MissingCompileTimeError
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 9cd8d2c..edefa0d 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -246,9 +246,6 @@
 async/zone_empty_description2_test: RuntimeError # Timer interface not supported: Issue 7728.
 mirrors/mirrors_reader_test: Skip # Running in v8 suffices. Issue 16589 - RuntimeError.  Issue 22130 - Crash (out of memory).
 
-[ $compiler == dart2js && $browser && !$csp && $fast_startup && $fasta ]
-async/stream_iterator_test: RuntimeError
-
 [ $compiler == dart2js && $checked ]
 convert/utf85_test: Pass, Slow # Issue 12029.
 
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index fa940e0..01f5583 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -411,9 +411,6 @@
 html/websql_test: Fail
 isolate/kill_self_synchronously_test: RuntimeError
 
-[ $compiler == dart2js && $runtime == ff && $fast_startup && $fasta ]
-html/fileapi_entry_test: RuntimeError
-
 [ $compiler == dart2js && $runtime == ie11 ]
 html/element_types_content_test: RuntimeError # Issue 29922
 html/element_types_datalist_test: RuntimeError # Issue 29922
@@ -520,21 +517,6 @@
 html/custom/element_upgrade_test: Fail # Issue 17298
 html/custom/js_custom_test: Fail # Issue 14643
 
-[ $compiler == dart2js && $browser && !$csp && $fast_startup && $fasta ]
-async/stream_iterator_test: RuntimeError
-html/fileapi_directory_reader_test: RuntimeError
-html/fileapi_directory_test: RuntimeError
-html/fileapi_file_entry_test: RuntimeError
-html/fileapi_file_test: RuntimeError
-html/fileapi_supported_test: RuntimeError
-html/fileapi_supported_throws_test: RuntimeError
-html/websql_test: RuntimeError
-isolate/browser/package_resolve_browser_hook2_test: RuntimeError
-isolate/browser/package_resolve_browser_test: RuntimeError
-
-[ $compiler == dart2js && $browser && $fast_startup && $fasta ]
-isolate/browser/package_resolve_browser_hook_test: RuntimeError
-
 [ $compiler == dart2js && !$browser && $fast_startup ]
 isolate/isolate_current_test: Fail # please triage
 
diff --git a/tools/VERSION b/tools/VERSION
index 47b0295..986a52a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 0
 PATCH 0
-PRERELEASE 37
+PRERELEASE 38
 PRERELEASE_PATCH 0
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index a1580fe..14c06a3 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -211,6 +211,27 @@
     },
     {
       "builders": [
+        "vm-kernel-legacy-linux-release-x64"
+      ],
+      "meta": {
+        "description": "Tests the vm with dartk in legacy mode."
+      },
+      "steps": [
+        {
+          "name": "build dart",
+          "script": "tools/build.py",
+          "arguments": ["runtime_kernel"]
+        },
+        {
+          "name": "vm legacy tests",
+          "arguments": ["--compiler=dartk"],
+          "fileset": "vm-kernel",
+          "shards": 10
+        }
+      ]
+    },
+    {
+      "builders": [
         "vm-kernel-precomp-linux-release-simarm",
         "vm-kernel-precomp-linux-release-simarm64",
         "vm-kernel-precomp-win-release-x64"
diff --git a/tools/patch_sdk.dart b/tools/patch_sdk.dart
index 8c06007..9dac1deb 100644
--- a/tools/patch_sdk.dart
+++ b/tools/patch_sdk.dart
@@ -23,7 +23,8 @@
 import 'package:front_end/src/fasta/util/relativize.dart' show relativizeUri;
 
 import 'package:front_end/src/fasta/get_dependencies.dart' show getDependencies;
-import 'package:front_end/src/fasta/kernel/utils.dart' show writeProgramToFile;
+import 'package:front_end/src/fasta/kernel/utils.dart'
+    show writeComponentToFile;
 
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/target/vm.dart' show VmTarget;
@@ -216,8 +217,8 @@
           false,
           inputs),
       buildSummary: true,
-      buildProgram: true);
-  await writeProgramToFile(result.program, output);
+      buildComponent: true);
+  await writeComponentToFile(result.component, output);
   return result.deps;
 }
 
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index ccbf1fd..b2d8477 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -34,6 +34,7 @@
 const int browserCrashExitCode = -10;
 const int parseFailExitCode = 245;
 const int slowTimeoutMultiplier = 4;
+const int extraSlowTimeoutMultiplier = 8;
 const int nonUtfFakeExitCode = 0xFFFD;
 
 const cannotOpenDisplayMessage = 'Gtk-WARNING **: cannot open display';
@@ -175,6 +176,8 @@
     var result = configuration.timeout;
     if (expectedOutcomes.contains(Expectation.slow)) {
       result *= slowTimeoutMultiplier;
+    } else if (expectedOutcomes.contains(Expectation.extraSlow)) {
+      result *= extraSlowTimeoutMultiplier;
     }
     return result;
   }
diff --git a/utils/bazel/kernel_summary_worker.dart b/utils/bazel/kernel_summary_worker.dart
index 3cfe4d6..461e390 100644
--- a/utils/bazel/kernel_summary_worker.dart
+++ b/utils/bazel/kernel_summary_worker.dart
@@ -16,7 +16,7 @@
 import 'package:bazel_worker/bazel_worker.dart';
 import 'package:front_end/src/api_unstable/summary_worker.dart' as fe;
 import 'package:front_end/src/multi_root_file_system.dart';
-import 'package:kernel/ast.dart' show Program, Library;
+import 'package:kernel/ast.dart' show Component, Library;
 import 'package:kernel/target/targets.dart';
 
 main(List<String> args) async {
@@ -175,21 +175,21 @@
       : super(flags);
 
   @override
-  void performOutlineTransformations(Program program) {
+  void performOutlineTransformations(Component component) {
     if (!excludeNonSources) return;
 
-    List<Library> libraries = new List.from(program.libraries);
-    program.libraries.clear();
+    List<Library> libraries = new List.from(component.libraries);
+    component.libraries.clear();
     Set<Uri> include = sources.toSet();
     for (var lib in libraries) {
       if (include.contains(lib.importUri)) {
-        program.libraries.add(lib);
+        component.libraries.add(lib);
       } else {
         // Excluding the library also means that their canonical names will not
         // be computed as part of serialization, so we need to do that
         // preemtively here to avoid errors when serializing references to
         // elements of these libraries.
-        program.root.getChildFromUri(lib.importUri).bindTo(lib.reference);
+        component.root.getChildFromUri(lib.importUri).bindTo(lib.reference);
         lib.computeCanonicalNames();
       }
     }
diff --git a/utils/compiler/BUILD.gn b/utils/compiler/BUILD.gn
index c9eaf7a..bcea398 100644
--- a/utils/compiler/BUILD.gn
+++ b/utils/compiler/BUILD.gn
@@ -45,7 +45,7 @@
   ]
 
   outputs = [
-    "$target_gen_dir/dart2js.dart"
+    "$target_gen_dir/dart2js.dart",
   ]
 
   args = [
@@ -58,9 +58,17 @@
 
 application_snapshot("dart2js") {
   deps = [
+    ":compile_dart2js_platform",
+    ":compile_dart2js_platform_strong",
     ":dart2js_create_snapshot_entry",
   ]
-  vm_args = ["--no_limit_ints_to_64_bits"]
+  inputs = [
+    "$root_out_dir/dart2js_platform.dill",
+    "$root_out_dir/dart2js_outline.dill",
+    "$root_out_dir/dart2js_platform_strong.dill",
+    "$root_out_dir/dart2js_outline_strong.dill",
+  ]
+  vm_args = [ "--no_limit_ints_to_64_bits" ]
   main_dart = "$target_gen_dir/dart2js.dart"
   training_args = [
     "--packages=" + rebase_path("../../.packages"),
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
index 8838af5..6ae3cd9 100644
--- a/utils/dartdevc/BUILD.gn
+++ b/utils/dartdevc/BUILD.gn
@@ -97,7 +97,16 @@
 
   compiled_action(target_name) {
     tool = "../../runtime/bin:dart"
-    inputs = sdk_lib_files + compiler_files + dev_compiler_files
+    deps = [
+      "../compiler:compile_dart2js_platform",
+      "../compiler:compile_dart2js_platform_strong",
+    ]
+    inputs = sdk_lib_files + compiler_files + dev_compiler_files + [
+               "$root_out_dir/dart2js_platform.dill",
+               "$root_out_dir/dart2js_outline.dill",
+               "$root_out_dir/dart2js_platform_strong.dill",
+               "$root_out_dir/dart2js_outline_strong.dill",
+             ]
     outputs = [
       out,
     ]
@@ -233,10 +242,10 @@
 group("dartdevc_test") {
   deps = [
     ":dartdevc",
-    ":dartdevk",
     ":dartdevc_sdk",
     ":dartdevc_sdk_kernel_summary",
     ":dartdevc_test_pkg",
+    ":dartdevk",
     "../../sdk:create_sdk",
   ]
 }