Version 2.0.0-dev.24.0

Merge commit '23fe39e89fcaeda926fb0fef1378ef48cad6a558' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0fd7c1c..204f682 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,10 @@
 * Added support for starting `async` functions synchronously. All tools (VM,
   dart2js, DDC) have now a flag `--sync-async` to enable this behavior.
   Currently this behavior is opt-in. It will become the default.
+* The type `void` is now a Top type like `dynamic`, and `Object`. It also now
+  has new errors for being used where not allowed (such as being assigned to any
+  non-`void`-typed parameter). Some libraries (importantly, mockito) may need to
+  be updated to accept void values to keep their APIs working.
 
 #### Strong Mode
 
diff --git a/DEPS b/DEPS
index 79b32bc..9b0a5cc 100644
--- a/DEPS
+++ b/DEPS
@@ -83,7 +83,7 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_tag": "@1.0.9",  # Please see the note above before updating.
 
-  "dartdoc_tag" : "@v0.15.1",
+  "dartdoc_tag" : "@v0.16.0",
   "fixnum_tag": "@0.10.5",
   "func_rev": "@25eec48146a58967d75330075ab376b3838b18a8",
   "glob_tag": "@1.1.5",
diff --git a/docs/language/Dart.g b/docs/language/Dart.g
index aa70500..827db76 100644
--- a/docs/language/Dart.g
+++ b/docs/language/Dart.g
@@ -802,9 +802,15 @@
 postfixExpression
     :    (assignableExpression postfixOperator) =>
          assignableExpression postfixOperator
+    |    (typeName typeArguments '.') =>
+         constructorInvocation ((selector) => selector)*
     |    primary ((selector) => selector)*
     ;
 
+constructorInvocation
+    :    typeName typeArguments '.' identifier arguments
+    ;
+
 postfixOperator
     :    incrementOperator
     ;
@@ -834,8 +840,11 @@
     :    (SUPER unconditionalAssignableSelector
             ~('<' | '(' | '[' | '.' | '?.')) =>
          SUPER unconditionalAssignableSelector
+    |    (typeName typeArguments '.' identifier '(') =>
+         constructorInvocation
+         ((assignableSelectorPart) => assignableSelectorPart)+
     |    (identifier ~('<' | '(' | '[' | '.' | '?.')) => identifier
-    |    (primary argumentPart* assignableSelector) =>
+    |    (primary assignableSelectorPart) =>
          primary ((assignableSelectorPart) => assignableSelectorPart)+
     |    identifier
     ;
@@ -947,7 +956,8 @@
     |    breakStatement
     |    continueStatement
     |    returnStatement
-    |    (functionSignature functionBodyPrefix) => localFunctionDeclaration
+    |    (metadata functionSignature functionBodyPrefix) =>
+         localFunctionDeclaration
     |    assertStatement
     |    (YIELD ~'*') => yieldStatement
     |    yieldEachStatement
@@ -967,7 +977,7 @@
     ;
 
 localFunctionDeclaration
-    :    functionSignature functionBody
+    :    metadata functionSignature functionBody
     ;
 
 ifStatement
diff --git a/docs/language/informal/implicit-creation.md b/docs/language/informal/implicit-creation.md
new file mode 100644
index 0000000..af5069c
--- /dev/null
+++ b/docs/language/informal/implicit-creation.md
@@ -0,0 +1,310 @@
+# Implicit Creation
+
+Author: eernst@.
+
+Version: 0.5 (2018-01-04)
+
+Status: Under implementation.
+
+**This document** is an informal specification of the *implicit creation* feature.
+**The feature** adds support for omitting some occurrences of the reserved words
+`new` and `const` in instance creation expressions.
+
+This feature specification was written with a
+[combined proposal](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new-const.md)
+as the starting point. That proposal presents optional new and optional const
+together with several other features.
+
+
+## Motivation
+
+In Dart without implicit creation, the reserved word `new` is present in
+almost all expressions whose evaluation invokes a constructor at run time,
+and `const` is present in the corresponding constant expressions. These
+expressions are known as *instance creation expressions*. If `new` or
+`const` is removed from such an instance creation expression, the remaining
+phrase is still syntactically correct in most cases. This feature
+specification updates the grammar to make them all syntactically correct.
+
+With that grammar update, all instance creation expressions can technically
+omit `new` or `const` because tools (compilers, analyzers) are able to
+parse these expressions.  The tools are able to recognize that these
+expressions denote instance creations (rather than, say, static function
+invocations), because the part before the arguments is statically known to
+denote a constructor.
+
+For instance, `p.C.foo` may resolve statically to a constructor named `foo` in
+a class `C` imported with prefix `p`. Similarly, `D` may resolve to a class, in
+which case `D(42)` is statically known to be a constructor invocation because
+the other interpretation is statically known to be incorrect (that is, cf.
+section '16.14.3 Unqualified Invocation' in the language specification,
+evaluating `(D)(42)`: `(D)` is an instance of `Type` which is not a function
+type and does not have a method named `call`, so we cannot call `(D)`).
+
+In short, even without the keyword, we can still unambiguously recognize the
+expressions that create objects. In that sense, the keywords are superfluous.
+
+For human readers, however, it may be helpful to document that a particular
+expression will yield a fresh instance, and this is the most common argument why
+`new` should *not* be omitted: It can be good documentation. But Dart already
+allows instance creation expressions to invoke a factory constructor, which is
+not guaranteed to return a newly created object, so Dart developers never had
+any firm local guarantees that any particular expression would yield a fresh
+object. This means that it may very well be justified to have an explicit `new`,
+but it will never be a rigorous guarantee of freshness.
+
+Similarly, it may be important for developers to ensure that certain expressions
+are constant, because of the improved performance and the guaranteed
+canonicalization. This is a compelling argument in favor of making certain
+instance creation expressions constant: It is simply a bug for that same
+expression to have `new` because object identity is an observable
+characteristic, and it may be crucial for performance that the expression is
+constant.
+
+In summary, both `new` and `const` may always be omitted from an instance
+creation expression, but it is useful and reasonable to allow an explicit `new`,
+and it is necessary to allow an explicit `const`. Based on that line of
+reasoning, we've decided to make them optional. It will then be possible for
+developers to make many expressions considerably more concise, and they can
+still enforce the desired semantics as needed.
+
+Obviously, this underscores the importance of the default: When a given instance
+creation expression omits the keyword, should it be `const` or `new`?
+
+**For instance creation expressions we have chosen** to use `const` whenever
+possible, and otherwise `new`.
+
+This implies that `const` is the preferred choice for instance creation. There
+is a danger that `const` is chosen by default in some cases where this is not
+intended by the developer, and the affected software will have bugs which are
+hard to spot. In particular, `e1 == e2` may evaluate to true in cases where it
+would have yielded false with `new` objects.
+
+We consider that danger to be rather small, because `const` can only be chosen
+in cases where the denoted constructor is constant, and with a class with a
+constant constructor it is necessary for developers to treat all accesses to its
+instances in such a way that the software will still work correctly even when
+any given instance was obtained by evaluation of a constant expression. The
+point is that, for such a class, we can never know for sure that any given
+instance is _not_ a constant object.
+
+With composite literals such as lists and maps, a `const` modifier may be
+included in order to make it a constant expression (which will of course fail if
+it contains something which is not a constant expression). In this case the
+presence of `const` may again be crucial, for the same reasons as with an
+instance creation expression, but it may also be crucial that `const` is _not_
+present, because the list or map will be mutated.
+
+**For composite literals we have chosen** to implicitly introduce `const`
+whenever it is required by the context.
+
+The choice to include `const` only when required by context (rather than
+whenever possible) is strictly less aggressive than the approach with instance
+creations. This choice is necessary because there is no way for developers to
+ensure that a literal like `[1, 2]` is mutable, if permitted by the context,
+other than omitting `const`.  Furthermore, we expect this choice to be
+convenient in practice, because mutable data structures are used frequently. So
+developers must expect to write an explicit `const` on composite literals now
+and then.
+
+In summary, the implicit creation feature allows for concise construction of
+objects, with a slight preference for constant expressions, and it still allows
+developers to explicitly specify `new` or `const`, whenever needed and whenever
+it is considered to be good documentation.
+
+
+## Syntax
+
+The syntax changes associated with this feature are the following:
+
+```
+postfixExpression ::=
+    assignableExpression postfixOperator |
+    constructorInvocation selector* |  // NEW
+    primary selector*
+constructorInvocation ::=  // NEW
+    typeName typeArguments '.' identifier arguments
+assignableExpression ::=
+    SUPER unconditionalAssignableSelector |
+    constructorInvocation assignableSelectorPart+ |  // NEW
+    identifier |
+    primary assignableSelectorPart+
+assignableSelectorPart ::=
+    argumentPart* assignableSelector
+```
+
+
+## Static analysis
+
+We specify a type directed source code transformation which eliminates the
+feature by expressing the same semantics with different syntax. The static
+analysis proceeds to work on the transformed program.
+
+*This means that the feature is "static semantic sugar". We do not specify the
+dynamic semantics for this feature, because the feature is eliminated in this
+transformation step.*
+
+We need to treat expressions differently in different locations, hence the
+following definition: An expression _e_ is said to *occur in a constant
+context*,
+
+- if _e_ is an element of a constant list literal, or a key or value of
+  an entry of a constant map literal.
+- if _e_ is an actual argument of a constant object expression or of a
+  metadata annotation.
+- if _e_ is the initializing expression of a constant variable declaration.
+- if _e_ is a switch case expression.
+- if _e_ is an immediate subexpression of an expression _e1_ which occurs in
+  a constant context, unless _e1_ is a `throw` expression or a function
+  literal.
+
+*This roughly means that everything which is inside a syntactically
+constant expression is in a constant context. Note that a `const` modifier
+which is introduced by the source code transformation does not create a
+constant context, it is only the explicit occurrences of `const` in the
+program that create a constant context. Also note that a `throw` expression
+is currently not allowed in a constant expression, but extensions affecting
+that status may be considered. A similar situation arises for function
+literals.*
+
+The transformation consists of two steps. In the first step, every literal
+list and literal map _e_ which occurs in a constant context and does not
+have the modifier `const` is replaced by `const` _e_.
+
+We define *new/const insertion* as the following transformation, which will
+be applied to specific parts of the program as specified below:
+
+- if the expression _e_ occurs in a constant context, replace _e_ by
+  `const` _e_,
+- if the expression _e_ does not occur in a constant context, but `const`
+  _e_ is a correct constant expression, replace _e_ by `const` _e_,
+- otherwise replace _e_ by `new` _e_.
+
+*Note that this transformation is applied in a bottom-up order which implies
+that all relevant transformations have already been applied on subexpressions
+of _e_. Also note that this transformation is only applied to syntactic
+constructs where the outcome is a syntactically correct instance creation
+expression. On the other hand, the outcome may have static semantic errors,
+e.g., actual arguments to a constructor invocation may have wrong types
+because that's how the program was written.*
+
+We define *new insertion* as the following transformation, which will be
+applied as specified below:
+
+- replace _e_ by `new` _e_.
+
+*We specify the second step of the transformation as based on a depth-first
+traversal of an abstract syntax tree (AST). This means that the program is
+assumed to be free of syntax errors, and when the current AST is, e.g., a
+`postfixExpression`, the program as a whole has such a structure that the
+current location was parsed as a `postfixExpression`. This is different
+from the situation where we just require that a given subsequence of the
+tokens of the program allows for such a parsing in isolation. For instance,
+an identifier like `x` parses as an `assignableExpression` in isolation,
+but if it occurs in the context `var x = 42;` or `var y = x;` then it will
+not be parsed as an `assignableExpression`, it will be parsed as a plain
+`identifier` which is part of a `declaredIdentifier` in the first case, and
+as a `primary` which is a `postfixExpression`, which is a
+`unaryExpression`, etc., in the second case. In short, we are transforming
+the AST of the program as a whole, not isolated snippets of code.*
+
+*In scientific literature, this kind of transformation is commonly
+specified as an inductive transformation where `[[e1 e2]] = [[e1]] [[e2]]`
+when the language supports a construct of the form `e1 e2`, etc. The reader
+may prefer to view the transformation in that light, and we would then say
+that we have omitted all the congruence rules.*
+
+An expression of one of the following forms must be modified in bottom-up
+order to be or contain a `constantObjectExpression` or `newExpression`
+as described:
+
+With a `postfixExpression` _e_,
+
+- if _e_ is of the form `constructorInvocation selector*`, i.e.,
+  `typeName typeArguments '.' identifier arguments selector*` then perform
+  new/const insertion on the initial `constructorInvocation`.
+- if _e_ is of the form
+  `typeIdentifier arguments` where `typeIdentifier` denotes a class then
+  perform new/const insertion on _e_.
+- if _e_ is of the form
+  `identifier1 '.' identifier2 arguments` where `identifier1` denotes
+  a class and `identifier2` is the name of a named constructor in that class,
+  or `identifier1` denotes a prefix for a library _L_ and `identifier2` denotes
+  a class exported by _L_, perform new/const insertion on _e_.
+- if _e_ is of the form
+  `identifier1 '.' typeIdentifier '.' identifier2 arguments` where
+  `identifier1` denotes a library prefix for a library _L_, `typeIdentifier`
+  denotes a class _C_ exported by _L_, and `identifier2` is the name of a named
+  constructor in _C_, perform new/const insertion on _e_.
+
+For the purposes of describing the transformation on assignable expressions
+we need the following syntactic entity:
+
+```
+assignableExpressionTail ::=
+    arguments assignableSelector assignableSelectorPart*
+```
+
+With an `assignableExpression` _e_,
+
+- if _e_ is of the form
+  `constructorInvocation assignableSelectorPart+`
+  then perform new/const insertion on the initial
+  `constructorInvocation`.
+- if _e_ is of the form
+  `typeIdentifier assignableExpressionTail`
+  where `typeIdentifier` denotes a class then perform new/const insertion on
+  the initial `typeIdentifier arguments`.
+- if _e_ is of the form
+  `typeIdentifier '.' identifier assignableExpressionTail`
+  where `typeIdentifier` denotes a class and `identifier` is the name of
+  a named constructor in that class, or `typeIdentifier` denotes a prefix
+  for a library _L_ and `identifier` denotes a class exported by _L_
+  then perform new/const insertion on the initial
+  `typeIdentifier '.' identifier arguments`.
+- if _e_ is of the form
+  `typeIdentifier1 '.' typeIdentifier2 '.' identifier assignableExpressionTail`
+  Where `typeIdentifier1` denotes a library prefix for a library _L_,
+  `typeIdentifier2` denotes a class _C_ exported by _L_, and `identifier`
+  is the name of a named constructor in _C_ then perform new/const insertion
+  on the initial
+  `typeIdentifier1 '.' typeIdentifier2 '.' identifier arguments`.
+
+*In short, add `const` wherever possible on terms that invoke a
+constructor, and otherwise add `new`. It is easy to verify that each of the
+replacements can be derived from `postfixExpression` via `primary
+selector*` and similarly for `assignableExpression`. Hence, the
+transformation preserves syntactic correctness.*
+
+
+## Dynamic Semantics
+
+There is no dynamic semantics to specify for this feature because it is
+eliminated by code transformation.
+
+
+## Revisions
+
+- 0.5 (2018-01-04) Rewritten to use `const` whenever possible (aka "magic
+  const") and adjusted to specify optional const as well as optional new
+  together, because they are now very closely connected. This document was
+  renamed to 'implicit-creation.md', and the document 'optional-const.md'
+  was deleted.
+
+- 0.4 (2017-10-17) Reverted to use 'immediate subexpression' again, for
+  correctness. Adjusted terminology for consistency. Clarified the semantics
+  of the transformation.
+
+- 0.3 (2017-09-08) Included missing rule for transformation of composite
+  literals (lists and maps). Eliminated the notion of an immediate
+  subexpression, for improved precision.
+
+- 0.2 (2017-07-30) Updated the document to specify the previously missing
+  transformations for `assignableExpression`, and to specify a no-magic
+  approach (where no `const` is introduced except when forced by the
+  syntactic context).
+
+- 0.1 (2017-08-15) Stand-alone informal specification for optional new created,
+  using version 0.8 of the combined proposal
+  [optional-new-const.md](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new-const.md)
+  as the starting point.
diff --git a/docs/language/informal/optional-const.md b/docs/language/informal/optional-const.md
deleted file mode 100644
index 9b79649..0000000
--- a/docs/language/informal/optional-const.md
+++ /dev/null
@@ -1,191 +0,0 @@
-# Optional const
-
-Author: eernst@.
-
-Version: 0.3 (2017-09-08)
-
-Status: Under implementation.
-
-**This document** is an informal specification of the *optional const* feature.
-**The feature** adds support for omitting the reserved word `const` in list and
-map literals and constant object expressions, in locations where `const` is
-currently required.
-
-This informal specification is built on a
-[combined proposal](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new-const.md)
-which presents optional const and several other features.
-
-## Motivation
-
-In Dart without optional const, complex constant expressions often contain many
-occurrences of `const` on list and map literals, and on constant object
-expressions. Subexpressions of constant expressions are themselves required to
-be constant expressions, and this means that `const` on a nested list or map
-literal provides no extra information: It is a compile-time error if that
-`const` is omitted. Similarly, it is a compile-time error if a nested constant
-object expression is modified to use `new` rather than `const`. In that
-situation it carries no extra information whether `new` or `const` is used, and
-it is even possible to omit the reserved word entirely. It is also required for
-certain other expressions to be constant, e.g., initializing expressions for
-constant variables.
-
-In all these cases the presence of `const` is required, and hence such a
-`const` may be inferred by compilers and similar tools if it is omitted.
-
-Developers reading the source code are likely to find it easy to understand
-that a required `const` was omitted and is implied, because the reason for
-the requirement is visible in the enclosing syntax: The expression where
-`const` is inferred is a subexpression of an expression with `const` or it
-is used in another situation where a constant value is required, e.g., to
-initialize a constant variable.
-
-In summary, tools do not need the required occurrences of `const`, and they
-are also unimportant for developers. Conversely, omitting required occurrences
-of `const` will sometimes make large expressions substantially more concise
-and readable, and also more convenient to write. Here is an example:
-
-```dart
-const myMap = const {
-  "a": const [const C("able"), const C("apple"), const C("axis")],
-  "b": const [const C("banana"), const C("bold"), const C("burglary")],
-};
-```
-
-Removing the required occurrences of `const` yields the following:
-
-```dart
-const myMap = {
-  "a": [C("able"), C("apple"), C("axis")],
-  "b": [C("banana"), C("bold"), C("burglary")],
-};
-```
-
-This proposal specifies that these previously required occurrences of `const`
-can be omitted, and will then be inferred.
-
-For a more detailed discussion and motivation, please consult the
-[combined proposal](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new-const.md)
-which covers optional const as well as several other proposals. That document
-was the starting point for this informal specification.
-
-## Syntax
-
-In order to support the optional const feature, the Dart grammar is modified as
-follows.
-
-```
-postfixExpression ::=
-    assignableExpression postfixOperator |
-    constructorInvocation |  // NEW
-    primary selector*
-constructorInvocation ::=  // NEW
-    typeName typeArguments '.' identifier arguments
-```
-
-*The grammar only needs to be adjusted for one case, namely invocations of named
-constructors for generic classes. In this case we can derive expressions like
-`const Foo<int>.bar()`, and the corresponding `Foo<int>.bar()` is not derivable
-in the same situations where the variant with `const` can be derived. In other
-words, we must add support for constructs like `Foo<int>.bar()` as part of a
-`postfixExpression`. For all other situations, the variant with `const` becomes
-a construct which is already syntactically correct Dart when the `const` is
-removed. For instance `const C(42)` becomes `C(42)` which is already allowed
-syntactically (it could be a function invocation).*
-
-## Static analysis
-
-We specify a type directed source code transformation which eliminates the
-feature. The static analysis proceeds to work on the transformed program.
-
-*This means that the feature is "sugar", but because of the need to refer
-to types it could be described as static semantic sugar rather than
-syntactic sugar. We do not specify the dynamic semantics for this feature,
-because the feature is eliminated in this transformation step.*
-
-We need to treat expressions differently in different locations, hence the
-following definition: An expression _e_ is said to *occur in a constant
-context*,
-
-- if _e_ is an element of a constant list literal, or a key or value of
-  an entry of a constant map literal.
-- if _e_ is an actual argument of a constant object expression or of a
-  metadata annotation.
-- if _e_ is the initializing expression of a constant variable declaration.
-- if _e_ is a switch case expression.
-- if _e_ is an immediate subexpression of an expression _e1_ which occurs in
-  a constant context, unless _e1_ is a `throw` expression or a function
-  literal.
-
-*This roughly means that everything which is inside a syntactically
-constant expression is in a constant context. A `throw` expression is
-currently not allowed in a constant expression, but extensions affecting
-that status may be considered. A similar situation arises for function
-literals.*
-
-*Note that the default value of an optional formal parameter is not a
-constant context. This choice reserves some freedom to modify the
-semantics of default values.*
-
-An expression on one of the following forms must be modified in top-down order
-to be or contain a `constantObjectExpression` as described:
-
-With a `postfixExpression` _e_ occurring in a constant context,
-
-- if _e_ is on the form `constructorInvocation` then replace _e_ by
-  `const` _e_.
-- if _e_ is on the form
-  `typeIdentifier arguments` where `typeIdentifier` denotes a class then
-  replace _e_ by `const` _e_.
-- if _e_ is on the form
-  `identifier1 '.' identifier2 arguments` where `identifier1` denotes
-  a class and `identifier2` is the name of a named constructor in that
-  class, or `identifier1` denotes a prefix for a library _L_ and
-  `identifier2` denotes a class exported by _L_, replace _e_ by
-  `const` _e_.
--  if _e_ is on the form
-  `identifier1 '.' typeIdentifier '.' identifier2 arguments` where
-  `identifier1` denotes a library prefix for a library _L_,
-  `typeIdentifier` denotes a class _C_ exported by _L_, and `identifier2`
-  is the name of a named constructor in _C_, replace _e_ by
-  `const` _e_.
-
-For a list literal _e_ occurring in a constant context, replace _e_ by 
-`const` _e_. For a map literal _e_ occurring in a constant context,
-replace _e_ by `const` _e_.
-
-*In short, in these specific situations: "just add `const`". It is easy to
-verify that each of the replacements can be derived from
-`constObjectExpression`, which can be derived from `postfixExpression` via
-`primary selector*`. Hence, the transformation preserves syntactic
-correctness.*
-
-The remaining static analysis proceeds to work on the transformed program.
-
-*It is possible that this transformation will create
-`constObjectExpressions` which violate the constraints on constant object
-expressions, e.g., when `const [[new A()]]` is transformed to
-`const [const [new A()]]` where the inner list is an error that was created
-by the transformation (so the error was moved from the outer to the inner
-list). It is recommended that the error messages emitted by tools in response
-to such violations include information about the transformation.*
-
-## Dynamic Semantics
-
-There is no dynamic semantics to specify for this feature because it is
-eliminated by code transformation.
-
-
-## Revisions
-
-- 0.3 (2017-09-08) Eliminated the notion of an immediate subexpression,
-  for improved precision.
-
-- 0.2 (2017-08-30) Updated the document to specify the previously missing
-  transformations for composite literals (lists and maps), and to specify a
-  no-magic approach (where no `const` is introduced except when forced by
-  the syntactic context).
-
-- 0.1 (2017-08-10) Stand-alone informal specification for optional const
-  created, using version 0.8 of the combined proposal
-  [optional-new-const.md](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new-const.md)
-  as the starting point.
diff --git a/docs/language/informal/optional-new.md b/docs/language/informal/optional-new.md
deleted file mode 100644
index 139f866..0000000
--- a/docs/language/informal/optional-new.md
+++ /dev/null
@@ -1,244 +0,0 @@
-# Optional new
-
-Author: eernst@.
-
-Version: 0.4 (2017-10-17)
-
-Status: Under implementation.
-
-**This document** is an informal specification of the *optional new* feature.
-**The feature** adds support for omitting the reserved word `new` in instance
-creation expressions.
-
-This feature extends and includes the
-[optional const feature](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-const.md),
-and it is assumed that the reader knows about optional const. Beyond
-that, this informal specification is derived from a
-[combined proposal](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new-const.md)
-which presents optional new together with several other features.
-
-
-## Motivation
-
-In Dart without optional new, the reserved word `new` is present in every
-expression whose evaluation invokes a constructor (except constant
-expressions). These expressions are known as *instance creation expressions*. If
-`new` is removed from such an instance creation expression, the remaining phrase
-is still syntactically correct in almost all cases. The required grammar
-update that makes them all syntactically correct is a superset of the one that
-is specified for
-[optional const](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-const.md).
-
-With that grammar update, all instance creation expressions can technically
-omit the `new` because tools (compilers, analyzers) are able to parse these
-expressions, and they are able to recognize that they denote instance creations
-(rather than, say, static function invocations), because the part before the
-left parenthesis is statically known to denote a constructor.
-
-For instance, `p.C.foo` may resolve statically to a constructor named `foo` in
-a class `C` imported with prefix `p`. Similarly, `D` may resolve to a class, in
-which case `D(42)` is statically known to be a constructor invocation because
-the other interpretation is statically known to be incorrect (that is, cf.
-section '16.14.3 Unqualified Invocation' in the language specification,
-evaluating `(D)(42)`: `(D)` is an instance of `Type` which is not a function
-type and does not have a method named `call`).
-
-For human readers, it may be helpful to document that a particular expression
-is guaranteed to yield a fresh instance, and this is the most common argument
-why `new` should *not* be omitted. However, Dart already allows instance
-creation expressions to invoke a factory constructor, so Dart developers never
-had any firm local guarantees that any particular expression would yield a
-fresh object.
-
-Developers may thus prefer to omit `new` in order to obtain more concise code,
-and possibly also in order to achieve greater uniformity among invocations of
-constructors and other invocations, e.g., of static or global functions.
-
-With that in mind, this proposal allows instance creation expressions to omit
-the `new` in all cases, but also preserves the permission to include `new` in
-all cases. It is a matter of style to use `new` in a manner that developers
-find helpful.
-
-
-## Syntax
-
-The syntax changes associated with this feature are the following:
-
-```
-postfixExpression ::=
-    assignableExpression postfixOperator |
-    constructorInvocation |  // NEW
-    primary selector*
-constructorInvocation ::=  // NEW
-    typeName typeArguments '.' identifier arguments
-assignableExpression ::=
-    SUPER unconditionalAssignableSelector |
-    constructorInvocation (arguments* assignableSelector)+ |  // NEW
-    identifier |
-    primary (arguments* assignableSelector)+
-```
-
-*As mentioned, this grammar update is a superset of the grammar update for
-[optional const](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-const.md).*
-
-
-## Static analysis
-
-We specify a type directed source code transformation which eliminates the
-feature by expressing the same semantics with different syntax. The static
-analysis proceeds to work on the transformed program.
-
-*Similarly to optional const, this means that the feature is "static semantic
-sugar". We do not specify the dynamic semantics for this feature, because the
-feature is eliminated in this transformation step.*
-
-We need to treat expressions differently in different locations, hence the
-following definition, which is identical to the one in
-[optional const](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-const.md):
-
-An expression _e_ is said to *occur in a constant context*,
-
-- if _e_ is an element of a constant list literal, or a key or value of
-  an entry of a constant map literal.
-- if _e_ is an actual argument of a constant object expression or of a
-  metadata annotation.
-- if _e_ is the initializing expression of a constant variable declaration.
-- if _e_ is a switch case expression.
-- if _e_ is an immediate subexpression of an expression _e1_ which occurs in
-  a constant context, unless _e1_ is a `throw` expression or a function
-  literal.
-
-*This roughly means that everything which is inside a syntactically
-constant expression is in a constant context. A `throw` expression is
-currently not allowed in a constant expression, but extensions affecting
-that status may be considered. A similar situation arises for function
-literals.*
-
-We define *new/const insertion* as the following transformation:
-
-- if the expression _e_ occurs in a constant context, replace _e_ by
-  `const` _e_,
-- otherwise replace _e_ by `new` _e_.
-
-We define *new insertion* as the following transformation:
-
-- replace _e_ by `new` _e_.
-
-For the purposes of describing the main transformation we need the following
-syntactic entity:
-
-```
-assignableExpressionTail ::=
-    arguments assignableSelector (arguments* assignableSelector)*
-```
-
-*We specify the transformation as based on a top-down traversal of an
-abstract syntax tree (AST). This means that the program is assumed to be
-free of syntax errors, and when the current AST is, e.g., a
-`postfixExpression`, the program as a whole has such a structure that
-the current location was parsed as a `postfixExpression`. This is
-different from the situation where we just require a given subsequence of the
-tokens of the program allows for such a parsing in isolation. For instance,
-an identifier like `x` parses as an `assignableExpression` in isolation,
-but if it occurs in the context `var x = 42;` or `var y = x;` then it
-will not be parsed as an `assignableExpression`, it will be parsed as a
-plain `identifier` which is part of a `declaredIdentifier` in the first
-case, and as a `primary` which is a `postfixExpression`, which is a
-`unaryExpression`, etc., in the second case. In short, we are
-transforming the AST of the program as a whole, not isolated snippets of
-code.*
-
-An expression of one of the following forms must be modified in top-down
-order to be or contain a `constantObjectExpression` or `newExpression`
-as described:
-
-With a `postfixExpression` _e_,
-
-- if _e_ is of the form `constructorInvocation`, i.e.,
-  `typeName typeArguments '.' identifier arguments` then perform
-  new/const insertion on _e_.
-- if _e_ is of the form
-  `typeIdentifier arguments` where `typeIdentifier` denotes a class then
-  perform new/const insertion on _e_.
-- if _e_ is of the form
-  `identifier1 '.' identifier2 arguments` where `identifier1` denotes
-  a class and `identifier2` is the name of a named constructor in that class,
-  or `identifier1` denotes a prefix for a library _L_ and `identifier2` denotes
-  a class exported by _L_, perform new/const insertion on _e_.
-- if _e_ is of the form
-  `identifier1 '.' typeIdentifier '.' identifier2 arguments` where
-  `identifier1` denotes a library prefix for a library _L_, `typeIdentifier`
-  denotes a class _C_ exported by _L_, and `identifier2` is the name of a named
-  constructor in _C_, perform new/const insertion on _e_.
-
-With an `assignableExpression` _e_,
-
-- if _e_ is of the form
-  `constructorInvocation assignableExpressionTail`
-  then perform new insertion on the initial
-  `constructorInvocation arguments`.
-- if _e_ is of the form
-  `typeIdentifier assignableExpressionTail`
-  where `typeIdentifier` denotes a class then perform new insertion on the
-  initial `typeIdentifier arguments`.
-- if _e_ is of the form
-  `identifier1 '.' identifier2 assignableExpressionTail`
-  where `identifier1` denotes a class and `identifier2` is the name of
-  a named constructor in that class, or `identifier1` denotes a prefix
-  for a library _L_ and `identifier2` denotes a class exported by _L_
-  then perform new insertion on the initial
-  `identifier1 '.' identifier2 arguments`.
-- if _e_ is of the form
-  `identifier1 '.' typeIdentifier '.' identifier2 assignableExpressionTail`
-  where `identifier1` denotes a library prefix for a library _L_,
-  `typeIdentifier` denotes a class _C_ exported by _L_, and `identifier2`
-  is the name of a named constructor in _C_ then perform new insertion
-  on the initial
-  `identifier1 '.' typeIdentifier '.' identifier2 arguments`.
-
-For a list literal _e_ occurring in a constant context, replace _e_ by
-`const` _e_. For a map literal _e_ occurring in a constant context,
-replace _e_ by `const` _e_.
-
-*In short, add `const` in const contexts and otherwise add `new`. With
-`assignableExpression` we always add `new`, because such an expression
-can never be a subexpression of a correct constant expression. It is easy
-to verify that each of the replacements can be derived from
-`postfixExpression` via `primary selector*` and similarly for
-`assignableExpression`. Hence, the transformation preserves syntactic
-correctness.*
-
-
-## Dynamic Semantics
-
-There is no dynamic semantics to specify for this feature because it is
-eliminated by code transformation.
-
-
-## Interplay with optional const
-
-This informal specification includes optional const as well as optional new,
-that is, if this specification is implemented then
-[optional const](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-const.md)
-may be considered as background material.
-
-
-## Revisions
-
-- 0.4 (2017-10-17) Reverted to use 'immediate subexpression' again, for
-  correctness. Adjusted terminology for consistency. Clarified the semantics
-  of the transformation.
-
-- 0.3 (2017-09-08) Included missing rule for transformation of composite
-  literals (lists and maps). Eliminated the notion of an immediate
-  subexpression, for improved precision.
-
-- 0.2 (2017-07-30) Updated the document to specify the previously missing
-  transformations for `assignableExpression`, and to specify a no-magic
-  approach (where no `const` is introduced except when forced by the
-  syntactic context).
-
-- 0.1 (2017-08-15) Stand-alone informal specification for optional new created,
-  using version 0.8 of the combined proposal
-  [optional-new-const.md](https://github.com/dart-lang/sdk/blob/master/docs/language/informal/optional-new-const.md)
-  as the starting point.
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 40612c7..a459c82 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -2808,6 +2808,13 @@
           additionally insert a template for the parameters. The information
           required in order to do so is contained in other fields.
         </p>
+      </dd><dt class="field"><b>displayText: String<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          Text to be displayed in, for example, a completion pop-up. This field
+          is only defined if the displayed text should be different than the
+          completion.  Otherwise it is omitted.
+        </p>
       </dd><dt class="field"><b>selectionOffset: int</b></dt><dd>
         
         <p>
@@ -2834,7 +2841,7 @@
         
         <p>
           An abbreviated version of the Dartdoc associated with the element
-          being suggested, This field is omitted if there is no Dartdoc
+          being suggested. This field is omitted if there is no Dartdoc
           associated with the element.
         </p>
       </dd><dt class="field"><b>docComplete: String<span style="color:#999999"> (optional)</span></b></dt><dd>
@@ -2968,7 +2975,12 @@
           suggestions of this kind, the completion is the named argument
           identifier including a trailing ':' and a space.
         </p>
-      </dd><dt class="value">OPTIONAL_ARGUMENT</dt><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_ContextData">ContextData: object</a></dt><dd>
+      </dd><dt class="value">OPTIONAL_ARGUMENT</dt><dt class="value">OVERRIDE</dt><dd>
+        
+        <p>
+          An overriding implementation of a class member is being suggested.
+        </p>
+      </dd><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_ContextData">ContextData: object</a></dt><dd>
     <p>
       Information about an analysis context.
     </p>
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index de63821..43aab94 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -372,6 +372,7 @@
 
     defaultContextOptions.generateImplicitErrors = false;
     defaultContextOptions.useFastaParser = options.useCFE;
+    defaultContextOptions.previewDart2 = options.previewDart2;
 
     {
       String name = options.newAnalysisDriverLog;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 6e50eb5..5442592 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -14,8 +14,8 @@
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 
 const ASYNC_STAR = 'async*';
-const DEFERRED_AS = 'deferred as';
 const DEFAULT_COLON = 'default:';
+const DEFERRED_AS = 'deferred as';
 const EXPORT_STATEMENT = "export '';";
 const IMPORT_STATEMENT = "import '';";
 const PART_STATEMENT = "part '';";
@@ -31,6 +31,12 @@
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
     List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+
+    // Don't suggest anything right after double or integer literals.
+    if (request.target.isDoubleOrIntLiteral()) {
+      return suggestions;
+    }
+
     request.target.containingNode
         .accept(new _KeywordVisitor(request, suggestions));
     return suggestions;
@@ -220,8 +226,14 @@
 
   @override
   visitConstructorDeclaration(ConstructorDeclaration node) {
-    if (node.initializers.isNotEmpty && node.initializers.last == entity) {
-      _addSuggestion(Keyword.SUPER);
+    if (node.initializers.isNotEmpty) {
+      if (entity is ConstructorInitializer) {
+        _addSuggestion(Keyword.ASSERT);
+      }
+      if (node.initializers.last == entity) {
+        _addSuggestion(Keyword.SUPER);
+        _addSuggestion(Keyword.THIS);
+      }
     }
   }
 
@@ -347,23 +359,6 @@
   }
 
   @override
-  visitParenthesizedExpression(ParenthesizedExpression node) {
-    Expression expression = node.expression;
-    if (expression is Identifier || expression is PropertyAccess) {
-      if (entity == node.rightParenthesis) {
-        var next = expression.endToken.next;
-        if (next == entity || next == droppedToken) {
-          // Fasta parses `if (x i^)` as `if (x ^) where the `i` is in the token
-          // stream but not part of the ParenthesizedExpression.
-          _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH);
-          return;
-        }
-      }
-    }
-    _addExpressionKeywords(node);
-  }
-
-  @override
   visitIfStatement(IfStatement node) {
     if (_isPreviousTokenSynthetic(entity, TokenType.CLOSE_PAREN)) {
       // Actual: if (x i^)
@@ -456,6 +451,23 @@
   }
 
   @override
+  visitParenthesizedExpression(ParenthesizedExpression node) {
+    Expression expression = node.expression;
+    if (expression is Identifier || expression is PropertyAccess) {
+      if (entity == node.rightParenthesis) {
+        var next = expression.endToken.next;
+        if (next == entity || next == droppedToken) {
+          // Fasta parses `if (x i^)` as `if (x ^) where the `i` is in the token
+          // stream but not part of the ParenthesizedExpression.
+          _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH);
+          return;
+        }
+      }
+    }
+    _addExpressionKeywords(node);
+  }
+
+  @override
   visitPrefixedIdentifier(PrefixedIdentifier node) {
     if (entity != node.identifier) {
       _addExpressionKeywords(node);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
index bce108a..4f58799 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/override_contributor.dart
@@ -63,13 +63,17 @@
    * Return a template for an override of the given [element]. If selected, the
    * template will replace [targetId].
    */
-  Future<String> _buildReplacementText(AnalysisResult result,
-      SimpleIdentifier targetId, ExecutableElement element) async {
+  Future<String> _buildReplacementText(
+      AnalysisResult result,
+      SimpleIdentifier targetId,
+      ExecutableElement element,
+      StringBuffer displayTextBuffer) async {
     DartChangeBuilder builder =
         new DartChangeBuilder(result.driver.currentSession);
     await builder.addFileEdit(result.path, (DartFileEditBuilder builder) {
       builder.addReplacement(range.node(targetId), (DartEditBuilder builder) {
-        builder.writeOverrideOfInheritedMember(element);
+        builder.writeOverrideOfInheritedMember(element,
+            displayTextBuffer: displayTextBuffer);
       });
     });
     return builder.sourceChange.edits[0].edits[0].replacement.trim();
@@ -81,11 +85,14 @@
    */
   Future<CompletionSuggestion> _buildSuggestion(DartCompletionRequest request,
       SimpleIdentifier targetId, ExecutableElement element) async {
-    String completion =
-        await _buildReplacementText(request.result, targetId, element);
+    StringBuffer displayTextBuffer = new StringBuffer();
+    String completion = await _buildReplacementText(
+        request.result, targetId, element, displayTextBuffer);
     if (completion == null || completion.length == 0) {
       return null;
     }
+    String displayText =
+        displayTextBuffer.isNotEmpty ? displayTextBuffer.toString() : null;
     CompletionSuggestion suggestion = new CompletionSuggestion(
         CompletionSuggestionKind.OVERRIDE,
         DART_RELEVANCE_HIGH,
@@ -93,7 +100,8 @@
         targetId.offset,
         0,
         element.isDeprecated,
-        false);
+        false,
+        displayText: displayText);
     suggestion.element = protocol.convertElement(element);
     return suggestion;
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index d983f08..b880b53 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -1466,7 +1466,9 @@
   }
 
   Future<Null> _addFix_createMissingOverrides() async {
-    // prepare target
+    if (node.parent is! ClassDeclaration) {
+      return;
+    }
     ClassDeclaration targetClass = node.parent as ClassDeclaration;
     ClassElement targetClassElement = targetClass.element;
     utils.targetClassElement = targetClassElement;
@@ -1613,6 +1615,9 @@
   }
 
   Future<Null> _addFix_createNoSuchMethod() async {
+    if (node.parent is! ClassDeclaration) {
+      return;
+    }
     ClassDeclaration targetClass = node.parent as ClassDeclaration;
     // prepare environment
     String prefix = utils.getIndent(1);
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 7173f6e..91b0f0d 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -201,6 +201,7 @@
  *   "kind": CompletionSuggestionKind
  *   "relevance": int
  *   "completion": String
+ *   "displayText": optional String
  *   "selectionOffset": int
  *   "selectionLength": int
  *   "isDeprecated": bool
@@ -231,6 +232,7 @@
           "isDeprecated": isBool,
           "isPotential": isBool
         }, optionalFields: {
+          "displayText": isString,
           "docSummary": isString,
           "docComplete": isString,
           "declaringType": isString,
@@ -258,6 +260,7 @@
  *   KEYWORD
  *   NAMED_ARGUMENT
  *   OPTIONAL_ARGUMENT
+ *   OVERRIDE
  *   PARAMETER
  * }
  */
@@ -270,6 +273,7 @@
   "KEYWORD",
   "NAMED_ARGUMENT",
   "OPTIONAL_ARGUMENT",
+  "OVERRIDE",
   "PARAMETER"
 ]);
 
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 3a8cfb8..bc58223 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -157,8 +157,8 @@
 
   Future<Response> waitForResponse(Request request) {
     String id = request.id;
-    return new Future<Response>(() => responseController.stream
-        .firstWhere((response) => response.id == id) as Future<Response>);
+    return responseController.stream
+        .firstWhere((response) => response.id == id);
   }
 }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 425178b..8568c03 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -837,6 +837,18 @@
     assertSuggestKeywords([]);
   }
 
+  test_constructor_initializers_first() async {
+    addTestSource('class A { int f; A() : ^, f = 1; }');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.ASSERT]);
+  }
+
+  test_constructor_initializers_last() async {
+    addTestSource('class A { A() : ^; }');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.ASSERT, Keyword.SUPER, Keyword.THIS]);
+  }
+
   test_constructor_param() async {
     addTestSource('class A { A(^) {});}');
     await computeSuggestions();
@@ -1411,6 +1423,18 @@
         relevance: DART_RELEVANCE_HIGH);
   }
 
+  test_integerLiteral_inArgumentList() async {
+    addTestSource('main() { print(42^); }');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
+  test_integerLiteral_inListLiteral() async {
+    addTestSource('main() { var items = [42^]; }');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
   test_is_expression() async {
     addTestSource('main() {if (x is^)}');
     await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 1fcab846..fd1701b 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -3113,7 +3113,20 @@
 ''');
   }
 
-  test_createNoSuchMethod() async {
+  test_createNoSuchMethod_BAD_classTypeAlias() async {
+    await resolveTestUnit('''
+abstract class A {
+  m();
+}
+
+class B = Object with A;
+''');
+    await assertNoFix(
+      DartFixKind.CREATE_NO_SUCH_METHOD,
+    );
+  }
+
+  test_createNoSuchMethod_OK() async {
     await resolveTestUnit('''
 abstract class A {
   m1();
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
index 7a8ebc3..582d655 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestion.java
@@ -54,6 +54,12 @@
   private final String completion;
 
   /**
+   * Text to be displayed in, for example, a completion pop-up. This field is only defined if the
+   * displayed text should be different than the completion. Otherwise it is omitted.
+   */
+  private final String displayText;
+
+  /**
    * The offset, relative to the beginning of the completion, of where the selection should be placed
    * after insertion.
    */
@@ -76,7 +82,7 @@
   private final boolean isPotential;
 
   /**
-   * An abbreviated version of the Dartdoc associated with the element being suggested, This field is
+   * An abbreviated version of the Dartdoc associated with the element being suggested. This field is
    * omitted if there is no Dartdoc associated with the element.
    */
   private final String docSummary;
@@ -163,10 +169,11 @@
   /**
    * Constructor for {@link CompletionSuggestion}.
    */
-  public CompletionSuggestion(String kind, int relevance, String completion, int selectionOffset, int selectionLength, boolean isDeprecated, boolean isPotential, String docSummary, String docComplete, String declaringType, String defaultArgumentListString, int[] defaultArgumentListTextRanges, Element element, String returnType, List<String> parameterNames, List<String> parameterTypes, Integer requiredParameterCount, Boolean hasNamedParameters, String parameterName, String parameterType, String importUri) {
+  public CompletionSuggestion(String kind, int relevance, String completion, String displayText, int selectionOffset, int selectionLength, boolean isDeprecated, boolean isPotential, String docSummary, String docComplete, String declaringType, String defaultArgumentListString, int[] defaultArgumentListTextRanges, Element element, String returnType, List<String> parameterNames, List<String> parameterTypes, Integer requiredParameterCount, Boolean hasNamedParameters, String parameterName, String parameterType, String importUri) {
     this.kind = kind;
     this.relevance = relevance;
     this.completion = completion;
+    this.displayText = displayText;
     this.selectionOffset = selectionOffset;
     this.selectionLength = selectionLength;
     this.isDeprecated = isDeprecated;
@@ -195,6 +202,7 @@
         ObjectUtilities.equals(other.kind, kind) &&
         other.relevance == relevance &&
         ObjectUtilities.equals(other.completion, completion) &&
+        ObjectUtilities.equals(other.displayText, displayText) &&
         other.selectionOffset == selectionOffset &&
         other.selectionLength == selectionLength &&
         other.isDeprecated == isDeprecated &&
@@ -221,6 +229,7 @@
     String kind = jsonObject.get("kind").getAsString();
     int relevance = jsonObject.get("relevance").getAsInt();
     String completion = jsonObject.get("completion").getAsString();
+    String displayText = jsonObject.get("displayText") == null ? null : jsonObject.get("displayText").getAsString();
     int selectionOffset = jsonObject.get("selectionOffset").getAsInt();
     int selectionLength = jsonObject.get("selectionLength").getAsInt();
     boolean isDeprecated = jsonObject.get("isDeprecated").getAsBoolean();
@@ -239,7 +248,7 @@
     String parameterName = jsonObject.get("parameterName") == null ? null : jsonObject.get("parameterName").getAsString();
     String parameterType = jsonObject.get("parameterType") == null ? null : jsonObject.get("parameterType").getAsString();
     String importUri = jsonObject.get("importUri") == null ? null : jsonObject.get("importUri").getAsString();
-    return new CompletionSuggestion(kind, relevance, completion, selectionOffset, selectionLength, isDeprecated, isPotential, docSummary, docComplete, declaringType, defaultArgumentListString, defaultArgumentListTextRanges, element, returnType, parameterNames, parameterTypes, requiredParameterCount, hasNamedParameters, parameterName, parameterType, importUri);
+    return new CompletionSuggestion(kind, relevance, completion, displayText, selectionOffset, selectionLength, isDeprecated, isPotential, docSummary, docComplete, declaringType, defaultArgumentListString, defaultArgumentListTextRanges, element, returnType, parameterNames, parameterTypes, requiredParameterCount, hasNamedParameters, parameterName, parameterType, importUri);
   }
 
   public static List<CompletionSuggestion> fromJsonArray(JsonArray jsonArray) {
@@ -290,6 +299,14 @@
   }
 
   /**
+   * Text to be displayed in, for example, a completion pop-up. This field is only defined if the
+   * displayed text should be different than the completion. Otherwise it is omitted.
+   */
+  public String getDisplayText() {
+    return displayText;
+  }
+
+  /**
    * The Dartdoc associated with the element being suggested. This field is omitted if there is no
    * Dartdoc associated with the element.
    */
@@ -298,7 +315,7 @@
   }
 
   /**
-   * An abbreviated version of the Dartdoc associated with the element being suggested, This field is
+   * An abbreviated version of the Dartdoc associated with the element being suggested. This field is
    * omitted if there is no Dartdoc associated with the element.
    */
   public String getDocSummary() {
@@ -426,6 +443,7 @@
     builder.append(kind);
     builder.append(relevance);
     builder.append(completion);
+    builder.append(displayText);
     builder.append(selectionOffset);
     builder.append(selectionLength);
     builder.append(isDeprecated);
@@ -452,6 +470,9 @@
     jsonObject.addProperty("kind", kind);
     jsonObject.addProperty("relevance", relevance);
     jsonObject.addProperty("completion", completion);
+    if (displayText != null) {
+      jsonObject.addProperty("displayText", displayText);
+    }
     jsonObject.addProperty("selectionOffset", selectionOffset);
     jsonObject.addProperty("selectionLength", selectionLength);
     jsonObject.addProperty("isDeprecated", isDeprecated);
@@ -523,6 +544,8 @@
     builder.append(relevance + ", ");
     builder.append("completion=");
     builder.append(completion + ", ");
+    builder.append("displayText=");
+    builder.append(displayText + ", ");
     builder.append("selectionOffset=");
     builder.append(selectionOffset + ", ");
     builder.append("selectionLength=");
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
index 32a42db..84048b8 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/CompletionSuggestionKind.java
@@ -51,6 +51,11 @@
 
   public static final String OPTIONAL_ARGUMENT = "OPTIONAL_ARGUMENT";
 
+  /**
+   * An overriding implementation of a class member is being suggested.
+   */
+  public static final String OVERRIDE = "OVERRIDE";
+
   public static final String PARAMETER = "PARAMETER";
 
 }
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index dcfe176..29e93e1 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -5046,7 +5046,7 @@
   /* TODO(leafp) Delete most of these.
    */
   static const StrongModeCode TOP_LEVEL_CYCLE = const StrongModeCode(
-      ErrorType.HINT,
+      ErrorType.COMPILE_TIME_ERROR,
       'TOP_LEVEL_CYCLE',
       "The type of '{0}' can't be inferred because it depends on itself through the cycle: {1}.",
       "Try adding an explicit type to one or more of the variables in the cycle in order to break the cycle.");
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index dc832df..c0be389 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -10567,8 +10567,7 @@
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
     listener.assertErrors([
-      expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER,
-          usingFastaParser ? 6 : 11, 1)
+      expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 6, 1)
     ]);
     expect(member, new isInstanceOf<ConstructorDeclaration>());
     NodeList<ConstructorInitializer> initializers =
@@ -10590,15 +10589,18 @@
     createParser('C() : this {}');
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
-    listener.assertErrors([
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 1),
-      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
-      usingFastaParser
-          ? expectedError(
-              ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 6, 4)
-          : expectedError(
-              ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 11, 1)
-    ]);
+    listener.assertErrors(usingFastaParser
+        ? [
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 1),
+            expectedError(
+                ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 6, 4)
+          ]
+        : [
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 1),
+            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
+            expectedError(
+                ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 11, 1)
+          ]);
   }
 
   void test_incomplete_constructorInitializers_thisField() {
@@ -10606,11 +10608,7 @@
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
     listener.assertErrors([
-      usingFastaParser
-          ? expectedError(
-              ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 6, 4)
-          : expectedError(
-              ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 8, 1)
+      expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 6, 4)
     ]);
   }
 
@@ -10620,11 +10618,7 @@
     expectNotNullIfNoErrors(member);
     listener.assertErrors([
       expectedError(ParserErrorCode.MISSING_IDENTIFIER, 12, 1),
-      usingFastaParser
-          ? expectedError(
-              ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 6, 4)
-          : expectedError(
-              ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 11, 1)
+      expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 6, 4)
     ]);
   }
 
@@ -10633,8 +10627,7 @@
     ClassMember member = parser.parseClassMember('C');
     expectNotNullIfNoErrors(member);
     listener.assertErrors([
-      expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER,
-          usingFastaParser ? 6 : 8, 1)
+      expectedError(ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER, 6, 1)
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart
index f8078ad..1b2fdee 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart
@@ -14,19 +14,70 @@
   buildAll() {
     List<TestDescriptor> descriptors = <TestDescriptor>[
       new TestDescriptor(
-          'ampersand', '@', [ParserErrorCode.MISSING_IDENTIFIER], '@_s_',
-          allFailing: true),
+        'ampersand',
+        '@',
+        [ParserErrorCode.MISSING_IDENTIFIER],
+        '@_s_',
+        allFailing: true,
+      ),
       new TestDescriptor(
-          'leftParen', '@a(', [ParserErrorCode.EXPECTED_TOKEN], '@a()',
-          allFailing: true),
+        'leftParen',
+        '@a(',
+        [ParserErrorCode.EXPECTED_TOKEN],
+        '@a()',
+        allFailing: true,
+      ),
     ];
-    buildTests('annotation_topLevel', descriptors,
-        PartialCodeTest.declarationSuffixes);
-    buildTests('annotation_classMember', descriptors,
-        PartialCodeTest.classMemberSuffixes,
-        head: 'class C { ', tail: ' }');
     buildTests(
-        'annotation_local', descriptors, PartialCodeTest.statementSuffixes,
-        head: 'f() { ', tail: ' }');
+      'annotation_topLevel',
+      expectErrors(descriptors, [ParserErrorCode.EXPECTED_EXECUTABLE]),
+      [],
+    );
+    buildTests(
+      'annotation_topLevel',
+      descriptors,
+      PartialCodeTest.declarationSuffixes,
+      includeEof: false,
+    );
+    buildTests(
+      'annotation_classMember',
+      descriptors,
+      PartialCodeTest.classMemberSuffixes,
+      head: 'class C { ',
+      tail: ' }',
+    );
+    buildTests(
+      'annotation_local',
+      expectErrors(descriptors, [
+        ParserErrorCode.EXPECTED_TOKEN,
+        ParserErrorCode.EXPECTED_TYPE_NAME,
+        ParserErrorCode.MISSING_IDENTIFIER,
+      ]),
+      [],
+      head: 'f() { ',
+      tail: ' }',
+    );
+    // TODO(brianwilkerson) Many of the combinations produced by the following
+    // produce "valid" code that is not valid. Even when we recover the
+    // annotation, the following statement is not allowed to have an annotation.
+    buildTests(
+      'annotation_local',
+      descriptors,
+      PartialCodeTest.statementSuffixes,
+      head: 'f() { ',
+      includeEof: false,
+      tail: ' }',
+    );
   }
+
+  /**
+   * Return a list of descriptors just like the given [descriptors] except that
+   * they have the given list of [errors] as the errors that are expected to be
+   * in the valid code.
+   */
+  List<TestDescriptor> expectErrors(
+          List<TestDescriptor> descriptors, List<ParserErrorCode> errors) =>
+      descriptors
+          .map((descriptor) => descriptor.withExpectedErrorsInValidCode(errors))
+          .toList();
 }
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/field_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/field_declaration_test.dart
index d1f7a02..5c42722 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/field_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/field_declaration_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:analyzer/src/error/codes.dart';
 
 import 'partial_code_support.dart';
 
@@ -22,217 +23,268 @@
       'setter'
     ];
     buildTests(
-        'field_declaration',
-        [
-          //
-          // Instance field, const.
-          //
-          new TestDescriptor(
-              'const_noName',
-              'const',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'const _s_;',
-              allFailing: true),
-          new TestDescriptor('const_name', 'const f',
-              [ParserErrorCode.EXPECTED_TOKEN], 'const f;',
-              allFailing: true),
-          new TestDescriptor(
-              'const_equals',
-              'const f =',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'const f = _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('const_initializer', 'const f = 0',
-              [ParserErrorCode.EXPECTED_TOKEN], 'const f = 0;'),
-          //
-          // Instance field, final.
-          //
-          new TestDescriptor(
-              'final_noName',
-              'final',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'final _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('final_name', 'final f',
-              [ParserErrorCode.EXPECTED_TOKEN], 'final f;',
-              failing: ['methodNonVoid', 'getter', 'setter']),
-          new TestDescriptor(
-              'final_equals',
-              'final f =',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'final f = _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('final_initializer', 'final f = 0',
-              [ParserErrorCode.EXPECTED_TOKEN], 'final f = 0;'),
-          //
-          // Instance field, var.
-          //
-          new TestDescriptor(
-              'var_noName',
-              'var',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'var _s_;',
-              failing: allExceptEof),
-          new TestDescriptor(
-              'var_name', 'var f', [ParserErrorCode.EXPECTED_TOKEN], 'var f;',
-              failing: ['methodNonVoid', 'getter', 'setter']),
-          new TestDescriptor(
-              'var_equals',
-              'var f =',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'var f = _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('var_initializer', 'var f = 0',
-              [ParserErrorCode.EXPECTED_TOKEN], 'var f = 0;'),
-          //
-          // Instance field, type.
-          //
-          new TestDescriptor(
-              'type_noName',
-              'A',
-              [
-                ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'A _s_;',
-              allFailing: true),
-          new TestDescriptor(
-              'type_name', 'A f', [ParserErrorCode.EXPECTED_TOKEN], 'A f;'),
-          new TestDescriptor(
-              'type_equals',
-              'A f =',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'A f = _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('type_initializer', 'A f = 0',
-              [ParserErrorCode.EXPECTED_TOKEN], 'A f = 0;'),
-          //
-          // Static field, const.
-          //
-          new TestDescriptor(
-              'static_const_noName',
-              'static const',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'static const _s_;',
-              allFailing: true),
-          new TestDescriptor('static_const_name', 'static const f',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static const f;',
-              allFailing: true),
-          new TestDescriptor(
-              'static_const_equals',
-              'static const f =',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'static const f = _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('static_const_initializer', 'static const f = 0',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static const f = 0;'),
-          //
-          // Static field, final.
-          //
-          new TestDescriptor(
-              'static_final_noName',
-              'static final',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'static final _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('static_final_name', 'static final f',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static final f;',
-              failing: ['methodNonVoid', 'getter', 'setter']),
-          new TestDescriptor(
-              'static_final_equals',
-              'static final f =',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'static final f = _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('static_final_initializer', 'static final f = 0',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static final f = 0;'),
-          //
-          // Static field, var.
-          //
-          new TestDescriptor(
-              'static_var_noName',
-              'static var',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'static var _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('static_var_name', 'static var f',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static var f;',
-              failing: ['methodNonVoid', 'getter', 'setter']),
-          new TestDescriptor(
-              'static_var_equals',
-              'static var f =',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'static var f = _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('static_var_initializer', 'static var f = 0',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static var f = 0;'),
-          //
-          // Static field, type.
-          //
-          new TestDescriptor(
-              'static_type_noName',
-              'static A',
-              [
-                ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'static A _s_;',
-              allFailing: true),
-          new TestDescriptor('static_type_name', 'static A f',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static A f;'),
-          new TestDescriptor(
-              'static_type_equals',
-              'static A f =',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'static A f = _s_;',
-              failing: allExceptEof),
-          new TestDescriptor('static_type_initializer', 'static A f = 0',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static A f = 0;'),
-        ],
-        PartialCodeTest.classMemberSuffixes,
-        head: 'class C { ',
-        tail: ' }');
+      'field_declaration',
+      [
+        //
+        // Instance field, const.
+        //
+        new TestDescriptor(
+          'const_noName',
+          'const',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'const _s_;',
+          allFailing: true,
+          expectedErrorsInValidCode: [
+            CompileTimeErrorCode.CONST_NOT_INITIALIZED
+          ],
+        ),
+        new TestDescriptor(
+          'const_name',
+          'const f',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'const f;',
+          allFailing: true,
+          expectedErrorsInValidCode: [
+            CompileTimeErrorCode.CONST_NOT_INITIALIZED
+          ],
+        ),
+        new TestDescriptor(
+          'const_equals',
+          'const f =',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'const f = _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'const_initializer',
+          'const f = 0',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'const f = 0;',
+        ),
+        //
+        // Instance field, final.
+        //
+        new TestDescriptor(
+          'final_noName',
+          'final',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'final _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'final_name',
+          'final f',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'final f;',
+          failing: ['methodNonVoid', 'getter', 'setter'],
+        ),
+        new TestDescriptor(
+          'final_equals',
+          'final f =',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'final f = _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'final_initializer',
+          'final f = 0',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'final f = 0;',
+        ),
+        //
+        // Instance field, var.
+        //
+        new TestDescriptor(
+          'var_noName',
+          'var',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'var _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'var_name',
+          'var f',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'var f;',
+          failing: ['methodNonVoid', 'getter', 'setter'],
+        ),
+        new TestDescriptor(
+          'var_equals',
+          'var f =',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'var f = _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'var_initializer',
+          'var f = 0',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'var f = 0;',
+        ),
+        //
+        // Instance field, type.
+        //
+        new TestDescriptor(
+          'type_noName',
+          'A',
+          [
+            ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
+          'A _s_;',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'type_name',
+          'A f',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'A f;',
+        ),
+        new TestDescriptor(
+          'type_equals',
+          'A f =',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'A f = _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'type_initializer',
+          'A f = 0',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'A f = 0;',
+        ),
+        //
+        // Static field, const.
+        //
+        new TestDescriptor(
+          'static_const_noName',
+          'static const',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'static const _s_;',
+          allFailing: true,
+          expectedErrorsInValidCode: [
+            CompileTimeErrorCode.CONST_NOT_INITIALIZED
+          ],
+        ),
+        new TestDescriptor(
+          'static_const_name',
+          'static const f',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static const f;',
+          allFailing: true,
+          expectedErrorsInValidCode: [
+            CompileTimeErrorCode.CONST_NOT_INITIALIZED
+          ],
+        ),
+        new TestDescriptor(
+          'static_const_equals',
+          'static const f =',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'static const f = _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'static_const_initializer',
+          'static const f = 0',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static const f = 0;',
+        ),
+        //
+        // Static field, final.
+        //
+        new TestDescriptor(
+          'static_final_noName',
+          'static final',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'static final _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'static_final_name',
+          'static final f',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static final f;',
+          failing: ['methodNonVoid', 'getter', 'setter'],
+        ),
+        new TestDescriptor(
+          'static_final_equals',
+          'static final f =',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'static final f = _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'static_final_initializer',
+          'static final f = 0',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static final f = 0;',
+        ),
+        //
+        // Static field, var.
+        //
+        new TestDescriptor(
+          'static_var_noName',
+          'static var',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'static var _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'static_var_name',
+          'static var f',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static var f;',
+          failing: ['methodNonVoid', 'getter', 'setter'],
+        ),
+        new TestDescriptor(
+          'static_var_equals',
+          'static var f =',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'static var f = _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'static_var_initializer',
+          'static var f = 0',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static var f = 0;',
+        ),
+        //
+        // Static field, type.
+        //
+        new TestDescriptor(
+          'static_type_noName',
+          'static A',
+          [
+            ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
+          'static A _s_;',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'static_type_name',
+          'static A f',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static A f;',
+        ),
+        new TestDescriptor(
+          'static_type_equals',
+          'static A f =',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'static A f = _s_;',
+          failing: allExceptEof,
+        ),
+        new TestDescriptor(
+          'static_type_initializer',
+          'static A f = 0',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static A f = 0;',
+        ),
+      ],
+      PartialCodeTest.classMemberSuffixes,
+      head: 'class C { ',
+      tail: ' }',
+    );
   }
 }
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/if_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/if_statement_test.dart
index 7f8ac54..6402a1c 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/if_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/if_statement_test.dart
@@ -13,33 +13,70 @@
 class IfStatementTest extends PartialCodeTest {
   buildAll() {
     buildTests(
-        'if_statement',
-        [
-          new TestDescriptor(
-              'keyword',
-              'if',
-              [
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "if (_s_)",
-              failing: ['eof']),
-          new TestDescriptor(
-              'leftParen',
-              'if (',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "if (_s_)",
-              allFailing: true),
-          new TestDescriptor(
-              'condition', 'if (a', [ParserErrorCode.EXPECTED_TOKEN], "if (a)",
-              allFailing: true),
-        ],
-        PartialCodeTest.statementSuffixes,
-        head: 'f() { ',
-        tail: ' }');
+      'if_statement',
+      [
+        new TestDescriptor(
+          'keyword',
+          'if',
+          [
+            ParserErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
+          "if (_s_)",
+        ),
+        new TestDescriptor(
+          'leftParen',
+          'if (',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          "if (_s_)",
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'condition',
+          'if (a',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          "if (a)",
+          allFailing: true,
+        ),
+      ],
+      PartialCodeTest.statementSuffixes,
+      head: 'f() { ',
+      includeEof: false,
+      tail: ' }',
+    );
+    buildTests(
+      'if_statement',
+      [
+        new TestDescriptor(
+          'keyword',
+          'if',
+          [
+            ParserErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
+          "if (_s_);",
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'leftParen',
+          'if (',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          "if (_s_);",
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'condition',
+          'if (a',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          "if (a);",
+          allFailing: true,
+        ),
+      ],
+      [],
+      head: 'f() { ',
+      tail: ' }',
+    );
   }
 }
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/method_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/method_declaration_test.dart
index 432d9d4..a2c8624 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/method_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/method_declaration_test.dart
@@ -13,183 +13,276 @@
 class MethodTest extends PartialCodeTest {
   buildAll() {
     buildTests(
-        'method_declaration',
-        [
-          //
-          // Instance method, no return type.
-          //
-          new TestDescriptor('noType_leftParen', 'm(',
-              [ParserErrorCode.EXPECTED_TOKEN], 'm();',
-              allFailing: true),
-          new TestDescriptor('noType_paramName', 'm(B',
-              [ParserErrorCode.EXPECTED_TOKEN], 'm(B);',
-              allFailing: true),
-          new TestDescriptor('noType_paramTypeAndName', 'm(B b',
-              [ParserErrorCode.EXPECTED_TOKEN], 'm(B b);',
-              allFailing: true),
-          new TestDescriptor(
-              'noType_paramAndComma',
-              'm(B b,',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'm(B b, _s_);',
-              allFailing: true),
-          new TestDescriptor('noType_noParams', 'm()',
-              [ParserErrorCode.EXPECTED_TOKEN], 'm();',
-              allFailing: true),
-          new TestDescriptor('noType_params', 'm(b, c)',
-              [ParserErrorCode.EXPECTED_TOKEN], 'm(b, c);',
-              allFailing: true),
-          new TestDescriptor(
-              'noType_emptyOptional',
-              'm(B b, [])',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_FUNCTION_BODY
-              ],
-              'm(B b, [_s_]){}'),
-          new TestDescriptor(
-              'noType_emptyNamed',
-              'm(B b, {})',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_FUNCTION_BODY
-              ],
-              'm(B b, {_s_}){}'),
-          //
-          // Instance method, with simple return type.
-          //
-          new TestDescriptor('type_leftParen', 'A m(',
-              [ParserErrorCode.EXPECTED_TOKEN], 'A m();',
-              allFailing: true),
-          new TestDescriptor('type_paramName', 'A m(B',
-              [ParserErrorCode.EXPECTED_TOKEN], 'A m(B);',
-              allFailing: true),
-          new TestDescriptor('type_paramTypeAndName', 'A m(B b',
-              [ParserErrorCode.EXPECTED_TOKEN], 'A m(B b);',
-              allFailing: true),
-          new TestDescriptor(
-              'type_paramAndComma',
-              'A m(B b,',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'A m(B b, _s_);',
-              allFailing: true),
-          new TestDescriptor('type_noParams', 'A m()',
-              [ParserErrorCode.EXPECTED_TOKEN], 'A m();',
-              allFailing: true),
-          new TestDescriptor('type_params', 'A m(b, c)',
-              [ParserErrorCode.EXPECTED_TOKEN], 'A m(b, c);',
-              allFailing: true),
-          new TestDescriptor(
-              'type_emptyOptional',
-              'A m(B b, [])',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_FUNCTION_BODY
-              ],
-              'A m(B b, [_s_]){}'),
-          new TestDescriptor(
-              'type_emptyNamed',
-              'A m(B b, {})',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_FUNCTION_BODY
-              ],
-              'A m(B b, {_s_}){}'),
-          //
-          // Static method, no return type.
-          //
-          new TestDescriptor('static_noType_leftParen', 'static m(',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static m();',
-              allFailing: true),
-          new TestDescriptor('static_noType_paramName', 'static m(B',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static m(B);',
-              allFailing: true),
-          new TestDescriptor('static_noType_paramTypeAndName', 'static m(B b',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static m(B b);',
-              allFailing: true),
-          new TestDescriptor(
-              'static_noType_paramAndComma',
-              'static m(B b,',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'static m(B b, _s_);',
-              allFailing: true),
-          new TestDescriptor('static_noType_noParams', 'static m()',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static m();',
-              allFailing: true),
-          new TestDescriptor('static_noType_params', 'static m(b, c)',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static m(b, c);',
-              allFailing: true),
-          new TestDescriptor(
-              'static_noType_emptyOptional',
-              'static m(B b, [])',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_FUNCTION_BODY
-              ],
-              'static m(B b, [_s_]){}'),
-          new TestDescriptor(
-              'static_noType_emptyNamed',
-              'static m(B b, {})',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_FUNCTION_BODY
-              ],
-              'static m(B b, {_s_}){}'),
-          //
-          // Static method, with simple return type.
-          //
-          new TestDescriptor('static_type_leftParen', 'static A m(',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static A m();',
-              allFailing: true),
-          new TestDescriptor('static_type_paramName', 'static A m(B',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static A m(B);',
-              allFailing: true),
-          new TestDescriptor('static_type_paramTypeAndName', 'static A m(B b',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static A m(B b);',
-              allFailing: true),
-          new TestDescriptor(
-              'static_type_paramAndComma',
-              'static A m(B b,',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              'static A m(B b, _s_);',
-              allFailing: true),
-          new TestDescriptor('static_type_noParams', 'static A m()',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static A m();',
-              allFailing: true),
-          new TestDescriptor('static_type_params', 'static A m(b, c)',
-              [ParserErrorCode.EXPECTED_TOKEN], 'static A m(b, c);',
-              allFailing: true),
-          new TestDescriptor(
-              'static_type_emptyOptional',
-              'static A m(B b, [])',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_FUNCTION_BODY
-              ],
-              'static A m(B b, [_s_]){}'),
-          new TestDescriptor(
-              'static_type_emptyNamed',
-              'static A m(B b, {})',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.MISSING_FUNCTION_BODY
-              ],
-              'static A m(B b, {_s_}){}'),
-        ],
-        PartialCodeTest.classMemberSuffixes,
-        head: 'class C { ',
-        tail: ' }');
+      'method_declaration',
+      [
+        //
+        // Instance method, no return type.
+        //
+        new TestDescriptor(
+          'noType_leftParen',
+          'm(',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'm();',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'noType_paramName',
+          'm(B',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'm(B);',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'noType_paramTypeAndName',
+          'm(B b',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'm(B b);',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'noType_paramAndComma',
+          'm(B b,',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'm(B b, _s_);',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'noType_noParams',
+          'm()',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'm();',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'noType_params',
+          'm(b, c)',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'm(b, c);',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'noType_emptyOptional',
+          'm(B b, [])',
+          [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.MISSING_FUNCTION_BODY
+          ],
+          'm(B b, [_s_]){}',
+        ),
+        new TestDescriptor(
+          'noType_emptyNamed',
+          'm(B b, {})',
+          [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.MISSING_FUNCTION_BODY
+          ],
+          'm(B b, {_s_}){}',
+        ),
+        //
+        // Instance method, with simple return type.
+        //
+        new TestDescriptor(
+          'type_leftParen',
+          'A m(',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'A m();',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'type_paramName',
+          'A m(B',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'A m(B);',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'type_paramTypeAndName',
+          'A m(B b',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'A m(B b);',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'type_paramAndComma',
+          'A m(B b,',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'A m(B b, _s_);',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'type_noParams',
+          'A m()',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'A m();',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'type_params',
+          'A m(b, c)',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'A m(b, c);',
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'type_emptyOptional',
+          'A m(B b, [])',
+          [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.MISSING_FUNCTION_BODY
+          ],
+          'A m(B b, [_s_]){}',
+        ),
+        new TestDescriptor(
+          'type_emptyNamed',
+          'A m(B b, {})',
+          [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.MISSING_FUNCTION_BODY
+          ],
+          'A m(B b, {_s_}){}',
+        ),
+        //
+        // Static method, no return type.
+        //
+        new TestDescriptor(
+          'static_noType_leftParen',
+          'static m(',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static m();',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_noType_paramName',
+          'static m(B',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static m(B);',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_noType_paramTypeAndName',
+          'static m(B b',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static m(B b);',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_noType_paramAndComma',
+          'static m(B b,',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'static m(B b, _s_);',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_noType_noParams',
+          'static m()',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static m();',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_noType_params',
+          'static m(b, c)',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static m(b, c);',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_noType_emptyOptional',
+          'static m(B b, [])',
+          [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.MISSING_FUNCTION_BODY
+          ],
+          'static m(B b, [_s_]){}',
+        ),
+        new TestDescriptor(
+          'static_noType_emptyNamed',
+          'static m(B b, {})',
+          [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.MISSING_FUNCTION_BODY
+          ],
+          'static m(B b, {_s_}){}',
+        ),
+        //
+        // Static method, with simple return type.
+        //
+        new TestDescriptor(
+          'static_type_leftParen',
+          'static A m(',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static A m();',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_type_paramName',
+          'static A m(B',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static A m(B);',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_type_paramTypeAndName',
+          'static A m(B b',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static A m(B b);',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_type_paramAndComma',
+          'static A m(B b,',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          'static A m(B b, _s_);',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_type_noParams',
+          'static A m()',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static A m();',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_type_params',
+          'static A m(b, c)',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          'static A m(b, c);',
+          allFailing: true,
+          expectedErrorsInValidCode: [ParserErrorCode.MISSING_FUNCTION_BODY],
+        ),
+        new TestDescriptor(
+          'static_type_emptyOptional',
+          'static A m(B b, [])',
+          [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.MISSING_FUNCTION_BODY
+          ],
+          'static A m(B b, [_s_]){}',
+        ),
+        new TestDescriptor(
+          'static_type_emptyNamed',
+          'static A m(B b, {})',
+          [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.MISSING_FUNCTION_BODY
+          ],
+          'static A m(B b, {_s_}){}',
+        ),
+      ],
+      PartialCodeTest.classMemberSuffixes,
+      head: 'class C { ',
+      tail: ' }',
+    );
   }
 }
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart
index ebb09d2..faaddf6 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/partial_code_support.dart
@@ -101,11 +101,13 @@
    */
   buildTests(String groupName, List<TestDescriptor> descriptors,
       List<TestSuffix> suffixes,
-      {String head, String tail}) {
+      {String head, bool includeEof: true, String tail}) {
     group(groupName, () {
       for (TestDescriptor descriptor in descriptors) {
-        _buildTestForDescriptorAndSuffix(
-            descriptor, TestSuffix.eof, 0, head, tail);
+        if (includeEof) {
+          _buildTestForDescriptorAndSuffix(
+              descriptor, TestSuffix.eof, 0, head, tail);
+        }
         for (int i = 0; i < suffixes.length; i++) {
           _buildTestForDescriptorAndSuffix(
               descriptor, suffixes[i], i + 1, head, tail);
@@ -113,9 +115,13 @@
         if (descriptor.failing != null) {
           test('${descriptor.name}_failingList', () {
             Set<String> failing = new Set.from(descriptor.failing);
-            failing.remove('eof');
+            if (includeEof) {
+              failing.remove('eof');
+            }
             failing.removeAll(suffixes.map((TestSuffix suffix) => suffix.name));
-            expect(failing, isEmpty);
+            expect(failing, isEmpty,
+                reason:
+                    'There are tests marked as failing that are not being run');
           });
         }
       }
@@ -155,8 +161,8 @@
         base.write(tail);
       }
       //
-      // Determine the existing errors in the code
-      // without either valid or invalid code.
+      // Determine the existing errors in the code without either valid or
+      // invalid code.
       //
       GatheringErrorListener listener =
           new GatheringErrorListener(checkRanges: true);
@@ -181,7 +187,6 @@
       if (descriptor.errorCodes != null) {
         expectedInvalidCodeErrors.addAll(descriptor.errorCodes);
       }
-
       //
       // Run the test.
       //
@@ -255,6 +260,17 @@
    */
   TestDescriptor(this.name, this.invalid, this.errorCodes, this.valid,
       {this.allFailing: false, this.failing, this.expectedErrorsInValidCode});
+
+  /**
+   * Return a new description that is exactly like this descriptor except with
+   * the given [expectedErrorsInValidCode].
+   */
+  TestDescriptor withExpectedErrorsInValidCode(
+          List<ErrorCode> expectedErrorsInValidCode) =>
+      new TestDescriptor(name, invalid, errorCodes, valid,
+          allFailing: allFailing,
+          failing: failing,
+          expectedErrorsInValidCode: expectedErrorsInValidCode);
 }
 
 /**
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
index 206cec2..17a1456 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+import 'package:analyzer/src/error/codes.dart';
 
 import 'partial_code_support.dart';
 
@@ -27,93 +28,170 @@
         'top_level_variable',
         [
           new TestDescriptor(
-              'const',
-              'const',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "const _s_;",
-              allFailing: true),
-          new TestDescriptor('constName', 'const a',
-              [ParserErrorCode.EXPECTED_TOKEN], "const a;",
-              allFailing: true),
-          new TestDescriptor('constTypeName', 'const int a',
-              [ParserErrorCode.EXPECTED_TOKEN], "const int a;",
-              allFailing: true),
+            'const',
+            'const',
+            [
+              ParserErrorCode.MISSING_IDENTIFIER,
+              ParserErrorCode.EXPECTED_TOKEN
+            ],
+            "const _s_;",
+            allFailing: true,
+            expectedErrorsInValidCode: [
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED
+            ],
+          ),
           new TestDescriptor(
-              'constNameComma',
-              'const a,',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "const a, _s_;",
-              allFailing: true),
+            'constName',
+            'const a',
+            [ParserErrorCode.EXPECTED_TOKEN],
+            "const a;",
+            allFailing: true,
+            expectedErrorsInValidCode: [
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED
+            ],
+          ),
           new TestDescriptor(
-              'constTypeNameComma',
-              'const int a,',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "const int a, _s_;",
-              allFailing: true),
-          new TestDescriptor('constNameCommaName', 'const a, b',
-              [ParserErrorCode.EXPECTED_TOKEN], "const a, b;",
-              allFailing: true),
-          new TestDescriptor('constTypeNameCommaName', 'const int a, b',
-              [ParserErrorCode.EXPECTED_TOKEN], "const int a, b;",
-              allFailing: true),
+            'constTypeName',
+            'const int a',
+            [ParserErrorCode.EXPECTED_TOKEN],
+            "const int a;",
+            allFailing: true,
+            expectedErrorsInValidCode: [
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED
+            ],
+          ),
           new TestDescriptor(
-              'final',
-              'final',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "final _s_;",
-              allFailing: true),
-          new TestDescriptor('finalName', 'final a',
-              [ParserErrorCode.EXPECTED_TOKEN], "final a;",
-              allFailing: true),
-          new TestDescriptor('finalTypeName', 'final int a',
-              [ParserErrorCode.EXPECTED_TOKEN], "final int a;",
-              allFailing: true),
+            'constNameComma',
+            'const a,',
+            [
+              ParserErrorCode.MISSING_IDENTIFIER,
+              ParserErrorCode.EXPECTED_TOKEN
+            ],
+            "const a, _s_;",
+            allFailing: true,
+            expectedErrorsInValidCode: [
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED
+            ],
+          ),
           new TestDescriptor(
-              'type',
-              'int',
-              [
-                ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "int _s_;",
-              allFailing: true),
+            'constTypeNameComma',
+            'const int a,',
+            [
+              ParserErrorCode.MISSING_IDENTIFIER,
+              ParserErrorCode.EXPECTED_TOKEN
+            ],
+            "const int a, _s_;",
+            allFailing: true,
+            expectedErrorsInValidCode: [
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED
+            ],
+          ),
           new TestDescriptor(
-              'typeName', 'int a', [ParserErrorCode.EXPECTED_TOKEN], "int a;"),
+            'constNameCommaName',
+            'const a, b',
+            [ParserErrorCode.EXPECTED_TOKEN],
+            "const a, b;",
+            allFailing: true,
+            expectedErrorsInValidCode: [
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED
+            ],
+          ),
           new TestDescriptor(
-              'var',
-              'var',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "var _s_;",
-              failing: allExceptEof),
+            'constTypeNameCommaName',
+            'const int a, b',
+            [ParserErrorCode.EXPECTED_TOKEN],
+            "const int a, b;",
+            allFailing: true,
+            expectedErrorsInValidCode: [
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED,
+              CompileTimeErrorCode.CONST_NOT_INITIALIZED
+            ],
+          ),
           new TestDescriptor(
-              'varName', 'var a', [ParserErrorCode.EXPECTED_TOKEN], "var a;",
-              failing: ['typedef', 'functionNonVoid', 'getter', 'setter']),
+            'final',
+            'final',
+            [
+              ParserErrorCode.MISSING_IDENTIFIER,
+              ParserErrorCode.EXPECTED_TOKEN
+            ],
+            "final _s_;",
+            allFailing: true,
+            expectedErrorsInValidCode: [
+              StaticWarningCode.FINAL_NOT_INITIALIZED
+            ],
+          ),
           new TestDescriptor(
-              'varNameEquals',
-              'var a =',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "var a = _s_;",
-              failing: allExceptEof),
-          new TestDescriptor('varNameEqualsExpression', 'var a = b',
-              [ParserErrorCode.EXPECTED_TOKEN], "var a = b;"),
+            'finalName',
+            'final a',
+            [ParserErrorCode.EXPECTED_TOKEN],
+            "final a;",
+            allFailing: true,
+            expectedErrorsInValidCode: [
+              StaticWarningCode.FINAL_NOT_INITIALIZED
+            ],
+          ),
+          new TestDescriptor(
+            'finalTypeName',
+            'final int a',
+            [ParserErrorCode.EXPECTED_TOKEN],
+            "final int a;",
+            allFailing: true,
+            expectedErrorsInValidCode: [
+              StaticWarningCode.FINAL_NOT_INITIALIZED
+            ],
+          ),
+          new TestDescriptor(
+            'type',
+            'int',
+            [
+              ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
+              ParserErrorCode.EXPECTED_TOKEN
+            ],
+            "int _s_;",
+            allFailing: true,
+          ),
+          new TestDescriptor(
+            'typeName',
+            'int a',
+            [ParserErrorCode.EXPECTED_TOKEN],
+            "int a;",
+          ),
+          new TestDescriptor(
+            'var',
+            'var',
+            [
+              ParserErrorCode.MISSING_IDENTIFIER,
+              ParserErrorCode.EXPECTED_TOKEN
+            ],
+            "var _s_;",
+            failing: allExceptEof,
+          ),
+          new TestDescriptor(
+            'varName',
+            'var a',
+            [ParserErrorCode.EXPECTED_TOKEN],
+            "var a;",
+            failing: ['typedef', 'functionNonVoid', 'getter', 'setter'],
+          ),
+          new TestDescriptor(
+            'varNameEquals',
+            'var a =',
+            [
+              ParserErrorCode.MISSING_IDENTIFIER,
+              ParserErrorCode.EXPECTED_TOKEN
+            ],
+            "var a = _s_;",
+            failing: allExceptEof,
+          ),
+          new TestDescriptor(
+            'varNameEqualsExpression',
+            'var a = b',
+            [ParserErrorCode.EXPECTED_TOKEN],
+            "var a = b;",
+          ),
         ],
         PartialCodeTest.declarationSuffixes);
   }
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart
index c7aa796..29040d2 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/while_statement_test.dart
@@ -13,33 +13,83 @@
 class WhileStatementTest extends PartialCodeTest {
   buildAll() {
     buildTests(
-        'while_statement',
-        [
-          new TestDescriptor(
-              'keyword',
-              'while',
-              [
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "while (_s_)",
-              failing: ['eof', 'break', 'continue']),
-          new TestDescriptor(
-              'leftParen',
-              'while (',
-              [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
-              "while (_s_)",
-              allFailing: true),
-          new TestDescriptor('condition', 'while (a',
-              [ParserErrorCode.EXPECTED_TOKEN], "while (a)",
-              allFailing: true),
-        ],
-        PartialCodeTest.statementSuffixes,
-        head: 'f() { ',
-        tail: ' }');
+      'while_statement',
+      <TestDescriptor>[
+        new TestDescriptor(
+          'keyword',
+          'while',
+          [
+            ParserErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
+          "while (_s_)",
+          allFailing: true,
+          expectedErrorsInValidCode: [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
+        ),
+        new TestDescriptor(
+          'leftParen',
+          'while (',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          "while (_s_)",
+          allFailing: true,
+          expectedErrorsInValidCode: [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
+        ),
+        new TestDescriptor(
+          'condition',
+          'while (a',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          "while (a)",
+          allFailing: true,
+          expectedErrorsInValidCode: [
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
+        ),
+      ],
+      [],
+      head: 'f() { ',
+      tail: ' }',
+    );
+    buildTests(
+      'while_statement',
+      <TestDescriptor>[
+        new TestDescriptor(
+          'keyword',
+          'while',
+          [
+            ParserErrorCode.EXPECTED_TOKEN,
+            ParserErrorCode.MISSING_IDENTIFIER,
+            ParserErrorCode.EXPECTED_TOKEN
+          ],
+          "while (_s_)",
+          failing: ['break', 'continue'],
+        ),
+        new TestDescriptor(
+          'leftParen',
+          'while (',
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
+          "while (_s_)",
+          allFailing: true,
+        ),
+        new TestDescriptor(
+          'condition',
+          'while (a',
+          [ParserErrorCode.EXPECTED_TOKEN],
+          "while (a)",
+          allFailing: true,
+        ),
+      ],
+      PartialCodeTest.statementSuffixes,
+      head: 'f() { ',
+      includeEof: false,
+      tail: ' }',
+    );
   }
 }
diff --git a/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart b/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
index 9a48970..af7574a 100644
--- a/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/recovery_test_support.dart
@@ -27,8 +27,11 @@
       validUnit =
           parseCompilationUnit(validCode, codes: expectedErrorsInValidCode);
     } catch (e) {
-      print('*** Valid code did not parse correctly');
-      print(validCode);
+      print('');
+      print('  Errors in valid code.');
+      print('    Error: $e');
+      print('    Code: $validCode');
+      print('');
       rethrow;
     }
 
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 60c028e..ebbb2f5 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -316,7 +316,7 @@
 
   @override
   void writeOverrideOfInheritedMember(ExecutableElement member,
-      {String returnTypeGroupName}) {
+      {StringBuffer, displayTextBuffer, String returnTypeGroupName}) {
     // prepare environment
     String prefix = getIndent(1);
     // may be property
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index b0dac1f..1ec6942 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -314,6 +314,19 @@
   }
 
   /**
+   * Return `true` if the target is a double or int literal.
+   */
+  bool isDoubleOrIntLiteral() {
+    var entity = this.entity;
+    if (entity is Token) {
+      TokenType previousTokenType = entity.previous?.type;
+      return previousTokenType == TokenType.DOUBLE ||
+          previousTokenType == TokenType.INT;
+    }
+    return false;
+  }
+
+  /**
    * Return `true` if the target is a functional argument in an argument list.
    * The target [AstNode] hierarchy *must* be resolved for this to work.
    * See [maybeFunctionalArgument].
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index 49cc0ea..171f216 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -113,6 +113,12 @@
    */
   factory OpType.forCompletion(CompletionTarget target, int offset) {
     OpType optype = new OpType._();
+
+    // Don't suggest anything right after double or integer literals.
+    if (target.isDoubleOrIntLiteral()) {
+      return optype;
+    }
+
     target.containingNode
         .accept(new _OpTypeAstVisitor(optype, target.entity, offset));
     var mthDecl =
@@ -280,6 +286,14 @@
   }
 
   @override
+  void visitAssertInitializer(AssertInitializer node) {
+    if (identical(entity, node.condition)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
   void visitAssertStatement(AssertStatement node) {
     if (identical(entity, node.condition)) {
       optype.includeReturnValueSuggestions = true;
diff --git a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
index 79d3f3c..a14dffc 100644
--- a/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/utilities/change_builder/change_builder_dart.dart
@@ -169,8 +169,11 @@
 
   /**
    * Append a placeholder for an override of the specified inherited [member].
+   * If provided, write a string value suitable for display (e.g., in a
+   * completion popup) in the given [displayTextBuffer].
    */
-  void writeOverrideOfInheritedMember(ExecutableElement member);
+  void writeOverrideOfInheritedMember(ExecutableElement member,
+      {StringBuffer displayTextBuffer});
 
   /**
    * Write the code for a parameter that would match the given [argument]. The
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
index e696ed4..4acdff3 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/change_builder_dart_test.dart
@@ -985,20 +985,25 @@
   }
 
   test_writeOverrideOfInheritedMember_method_nullAsTypeArgument() async {
-    await _assertWriteOverrideOfInheritedMethod('''
+    await _assertWriteOverrideOfInheritedMethod(
+      '''
 abstract class A {
   List<Null> foo();
 }
 
 class B extends A {
 }
-''', '''
+''',
+      '''
 @override
 List<Null> foo() {
   // TODO: implement foo
   return null;
 }
-''');
+''',
+      // TODO(pquitslund): Add tests once implemented.
+      //displayText: 'foo() { ... }'
+    );
   }
 
   test_writeOverrideOfInheritedMember_method_voidAsTypeArgument() async {
@@ -1440,20 +1445,26 @@
    * an inherited method is to be added, assert that the text of the overridden
    * member matches the [expected] text (modulo white space).
    */
-  _assertWriteOverrideOfInheritedMethod(String content, String expected) async {
+  _assertWriteOverrideOfInheritedMethod(String content, String expected,
+      {String displayText}) async {
     String path = provider.convertPath('/test.dart');
     addSource(path, content);
     ClassElement classA = await _getClassElement(path, 'A');
 
+    StringBuffer displayBuffer =
+        displayText != null ? new StringBuffer() : null;
+
     DartChangeBuilderImpl builder = new DartChangeBuilder(session);
     await builder.addFileEdit(path, (FileEditBuilder builder) {
       builder.addInsertion(content.length - 2, (EditBuilder builder) {
-        (builder as DartEditBuilder)
-            .writeOverrideOfInheritedMember(classA.methods[0]);
+        (builder as DartEditBuilder).writeOverrideOfInheritedMember(
+            classA.methods[0],
+            displayTextBuffer: displayBuffer);
       });
     });
     SourceEdit edit = getEdit(builder);
     expect(edit.replacement, equalsIgnoringWhitespace(expected));
+    expect(displayBuffer?.toString(), displayText);
   }
 
   Future<ClassElement> _getClassElement(String path, String name) async {
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
index ddc6cc8..fff6171 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/optype_test.dart
@@ -223,6 +223,11 @@
     await assertOpType(returnValue: true, typeNames: true);
   }
 
+  test_AssertInitializer() async {
+    addTestSource('class C { C() : assert(^); }');
+    await assertOpType(returnValue: true, typeNames: true);
+  }
+
   test_AssignmentExpression_name() async {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
@@ -1173,6 +1178,21 @@
     await assertOpType(returnValue: true, typeNames: true);
   }
 
+  test_IntegerLiteral_inArgumentList() async {
+    addTestSource('main() { print(1^); }');
+    await assertOpType();
+  }
+
+  test_IntegerLiteral_inListLiteral() async {
+    addTestSource('main() { var items = [1^]; }');
+    await assertOpType();
+  }
+
+  test_DoubleLiteral() async {
+    addTestSource('main() { print(1.2^); }');
+    await assertOpType();
+  }
+
   test_IsExpression_type_partial() async {
     // SimpleIdentifier  TypeName  IsExpression  IfStatement
     addTestSource('main(){var a; if (a is Obj^)}');
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 19d3b29..36ac2da 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -289,6 +289,8 @@
 
   void setUseKernel(String argument) {
     useKernel = true;
+    // TODO(sigmund): reenable hints (Issue #32111)
+    showHints = false;
     passThrough(argument);
   }
 
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 5ea9202..4313798 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -1166,6 +1166,8 @@
   InterfaceType getSupertype(ClassEntity cls);
 
   /// Returns all supertypes of [cls].
+  // TODO(johnniwinther): This should include `Function` if [cls] declares
+  // a `call` method.
   Iterable<InterfaceType> getSupertypes(ClassEntity cls);
 
   /// Returns all types directly implemented by [cls].
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 1131467..9a025ac 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -987,15 +987,11 @@
     BackendImpacts impacts =
         new BackendImpacts(compiler.options, closedWorld.commonElements);
     if (compiler.options.disableRtiOptimization) {
-      _rtiSubstitutions = new TrivialRuntimeTypesSubstitutions(
-          closedWorld.elementEnvironment, closedWorld.dartTypes);
+      _rtiSubstitutions = new TrivialRuntimeTypesSubstitutions(closedWorld);
       _rtiChecksBuilder =
           new TrivialRuntimeTypesChecksBuilder(closedWorld, _rtiSubstitutions);
     } else {
-      RuntimeTypesImpl runtimeTypesImpl = new RuntimeTypesImpl(
-          closedWorld.commonElements,
-          closedWorld.elementEnvironment,
-          closedWorld.dartTypes);
+      RuntimeTypesImpl runtimeTypesImpl = new RuntimeTypesImpl(closedWorld);
       _rtiChecksBuilder = runtimeTypesImpl;
       _rtiSubstitutions = runtimeTypesImpl;
     }
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 90cbe16..3a880dc 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -27,7 +27,7 @@
 /// For each class, stores the possible class subtype tests that could succeed.
 abstract class TypeChecks {
   /// Get the set of checks required for class [element].
-  Iterable<TypeCheck> operator [](ClassEntity element);
+  ClassChecks operator [](ClassEntity element);
 
   /// Get the iterable for all classes that need type checks.
   Iterable<ClassEntity> get classes;
@@ -167,8 +167,8 @@
   /// in the return type or the argument types.
   Iterable<ClassEntity> getReferencedClasses(FunctionType type);
 
-  /// Return all classes that use type arguments.
-  Iterable<ClassEntity> getRequiredArgumentClasses();
+  /// Return all classes needed for runtime type information.
+  Iterable<ClassEntity> get requiredClasses;
 
   /// Return all classes immediately used in explicit or implicit is-tests.
   ///
@@ -202,7 +202,7 @@
   TypeChecks get requiredChecks => _typeChecks;
 
   @override
-  Iterable<ClassEntity> getRequiredArgumentClasses() => _allClasses;
+  Iterable<ClassEntity> get requiredClasses => _allClasses;
 
   @override
   Iterable<ClassEntity> getReferencedClasses(FunctionType type) => _allClasses;
@@ -245,13 +245,20 @@
   @override
   RuntimeTypesChecks computeRequiredChecks(
       CodegenWorldBuilder codegenWorldBuilder) {
-    Set<ClassEntity> classes = _closedWorld
-        .getClassSet(_closedWorld.commonElements.objectClass)
-        .subtypes()
-        .toSet();
     rtiChecksBuilderClosed = true;
+    ClassUse classUse = new ClassUse()
+      ..instance = true
+      ..checkedInstance = true
+      ..typeArgument = true
+      ..checkedTypeArgument = true;
+    Map<ClassEntity, ClassUse> classUseMap = <ClassEntity, ClassUse>{};
+    for (ClassEntity cls in _closedWorld
+        .getClassSet(_closedWorld.commonElements.objectClass)
+        .subtypes()) {
+      classUseMap[cls] = classUse;
+    }
     TypeChecks typeChecks = _substitutions._requiredChecks =
-        _substitutions._computeChecks(classes, classes);
+        _substitutions._computeChecks(classUseMap);
     return new TrivialTypesChecks(typeChecks);
   }
 
@@ -285,31 +292,215 @@
 
 abstract class RuntimeTypesSubstitutionsMixin
     implements RuntimeTypesSubstitutions {
-  ElementEnvironment get _elementEnvironment;
-  DartTypes get _types;
+  ClosedWorld get _closedWorld;
   TypeChecks get _requiredChecks;
 
-  TypeChecks _computeChecks(
-      Iterable<ClassEntity> instantiated, Iterable<ClassEntity> checked) {
+  ElementEnvironment get _elementEnvironment => _closedWorld.elementEnvironment;
+  DartTypes get _types => _closedWorld.dartTypes;
+  RuntimeTypesNeed get _rtiNeed => _closedWorld.rtiNeed;
+
+  /// Compute the required type checks and substitutions for the given
+  /// instantiated and checked classes.
+  TypeChecks _computeChecks(Map<ClassEntity, ClassUse> classUseMap) {
     // Run through the combination of instantiated and checked
     // arguments and record all combination where the element of a checked
     // argument is a superclass of the element of an instantiated type.
     TypeCheckMapping result = new TypeCheckMapping();
-    for (ClassEntity element in instantiated) {
-      if (checked.contains(element)) {
-        result.add(element, element, null);
+    Set<ClassEntity> handled = new Set<ClassEntity>();
+
+    // Empty usage object for classes with no direct rti usage.
+    final ClassUse emptyUse = new ClassUse();
+
+    /// Compute the $isX and $asX functions need for [cls].
+    ClassChecks computeChecks(ClassEntity cls) {
+      if (!handled.add(cls)) return result[cls];
+
+      ClassChecks checks = new ClassChecks();
+      result[cls] = checks;
+      ClassUse classUse = classUseMap[cls] ?? emptyUse;
+
+      // Find the superclass from which [cls] inherits checks.
+      ClassEntity superClass = _elementEnvironment.getSuperClass(cls,
+          skipUnnamedMixinApplications: true);
+      ClassChecks superChecks;
+      bool extendsSuperClassTrivially = false;
+      if (superClass != null) {
+        // Compute the checks inherited from [superClass].
+        superChecks = computeChecks(superClass);
+
+        // Does [cls] extend [superClass] trivially?
+        //
+        // For instance:
+        //
+        //     class A<T> {}
+        //     class B<S> extends A<S> {}
+        //     class C<U, V> extends A<U> {}
+        //     class D extends A<int> {}
+        //
+        // here `B` extends `A` trivially, but `C` and `D` don't.
+        extendsSuperClassTrivially = isTrivialSubstitution(cls, superClass);
       }
-      // Find all supertypes of [element] in [checkedArguments] and add checks
-      // and precompute the substitutions for them.
-      for (InterfaceType supertype in _types.getSupertypes(element)) {
-        ClassEntity superelement = supertype.element;
-        if (checked.contains(superelement)) {
-          Substitution substitution =
-              computeSubstitution(element, superelement);
-          result.add(element, superelement, substitution);
+
+      bool isNativeClass = _closedWorld.nativeData.isNativeClass(cls);
+      if (classUse.typeArgument ||
+          (isNativeClass && classUse.checkedInstance)) {
+        // We need [cls] at runtime - even if [cls] is not instantiated. Either
+        // as a type argument or for an is-test if [cls] is native.
+        checks.add(new TypeCheck(cls, null, needsIs: isNativeClass));
+      }
+
+      // Compute the set of classes that [cls] inherited properties from.
+      //
+      // This set reflects the emitted class hierarchy and therefore uses
+      // `getEffectiveMixinClass` to find the inherited mixins.
+      Set<ClassEntity> inheritedClasses = new Set<ClassEntity>();
+      ClassEntity other = cls;
+      while (other != null) {
+        inheritedClasses.add(other);
+        if (_elementEnvironment.isMixinApplication(other)) {
+          inheritedClasses
+              .add(_elementEnvironment.getEffectiveMixinClass(other));
+        }
+        other = _elementEnvironment.getSuperClass(other);
+      }
+
+      /// Compute the needed check for [cls] against the class of the super
+      /// [type].
+      void processSupertype(InterfaceType type) {
+        ClassEntity checkedClass = type.element;
+        ClassUse checkedClassUse = classUseMap[checkedClass] ?? emptyUse;
+
+        // Where [cls] inherits properties for [checkedClass].
+        bool inheritsFromCheckedClass = inheritedClasses.contains(checkedClass);
+
+        // If [cls] inherits properties from [checkedClass] and [checkedClass]
+        // needs type arguments, [cls] must provide a substitution for
+        // [checkedClass].
+        //
+        // For instance:
+        //
+        //     class M<T> {
+        //        m() => T;
+        //     }
+        //     class S {}
+        //     class C extends S with M<int> {}
+        //
+        // Here `C` needs an `$asM` substitution function to provide the value
+        // of `T` in `M.m`.
+        bool needsTypeArgumentsForCheckedClass = inheritsFromCheckedClass &&
+            _rtiNeed.classNeedsTypeArguments(checkedClass);
+
+        // Whether [checkedClass] is used in an instance test or type argument
+        // test.
+        //
+        // For instance:
+        //
+        //    class A {}
+        //    class B {}
+        //    test(o) => o is A || o is List<B>;
+        //
+        // Here `A` is used in an instance test and `B` is used in a type
+        // argument test.
+        bool isChecked = checkedClassUse.checkedTypeArgument ||
+            checkedClassUse.checkedInstance;
+
+        if (isChecked || needsTypeArgumentsForCheckedClass) {
+          // We need an $isX and/or $asX property on [cls] for [checkedClass].
+
+          // Whether `cls` implements `checkedClass` trivially.
+          //
+          // For instance:
+          //
+          //     class A<T> {}
+          //     class B<S> implements A<S> {}
+          //     class C<U, V> implements A<U> {}
+          //     class D implements A<int> {}
+          //
+          // here `B` implements `A` trivially, but `C` and `D` don't.
+          bool implementsCheckedTrivially =
+              isTrivialSubstitution(cls, checkedClass);
+
+          // Whether [checkedClass] is generic.
+          //
+          // Currently [isTrivialSubstitution] reports that [cls] implements
+          // [checkedClass] trivially if [checkedClass] is not generic. In this
+          // case the substitution is not only trivial it is also not needed.
+          bool isCheckedGeneric =
+              _elementEnvironment.isGenericClass(checkedClass);
+
+          // The checks for [checkedClass] inherited for [superClass].
+          TypeCheck checkFromSuperClass =
+              superChecks != null ? superChecks[checkedClass] : null;
+
+          // Whether [cls] need an explicit $isX property for [checkedClass].
+          //
+          // If [cls] inherits from [checkedClass] it also inherits the $isX
+          // property automatically generated on [checkedClass].
+          bool needsIs = !inheritsFromCheckedClass && isChecked;
+
+          if (checkFromSuperClass != null) {
+            // The superclass has a substitution function for [checkedClass].
+            // Check if we can reuse this it of need to override it.
+            //
+            // The inherited $isX property does _not_ need to be overriding.
+            if (extendsSuperClassTrivially) {
+              // [cls] implements [checkedClass] the same way as [superClass]
+              // so the inherited substitution function already works.
+              checks.add(new TypeCheck(checkedClass, null, needsIs: false));
+            } else {
+              // [cls] implements [checkedClass] differently from [superClass]
+              // so the inherited substitution function needs to be replaced.
+              if (implementsCheckedTrivially) {
+                // We need an explicit trivial substitution function for
+                // [checkedClass] that overrides the inherited function.
+                checks.add(new TypeCheck(checkedClass,
+                    isCheckedGeneric ? const Substitution.trivial() : null,
+                    needsIs: false));
+              } else {
+                // We need a non-trivial substitution function for
+                // [checkedClass].
+                checks.add(new TypeCheck(
+                    checkedClass, computeSubstitution(cls, checkedClass),
+                    needsIs: false));
+              }
+            }
+          } else {
+            // The superclass has no substitution function for [checkedClass].
+            if (implementsCheckedTrivially) {
+              // We don't add an explicit substitution function for
+              // [checkedClass] because the substitution is trivial and doesn't
+              // need to override an inherited function.
+              checks.add(new TypeCheck(checkedClass, null, needsIs: needsIs));
+            } else {
+              // We need a non-trivial substitution function for
+              // [checkedClass].
+              checks.add(new TypeCheck(
+                  checkedClass, computeSubstitution(cls, checkedClass),
+                  needsIs: needsIs));
+            }
+          }
         }
       }
+
+      for (InterfaceType type in _types.getSupertypes(cls)) {
+        processSupertype(type);
+      }
+      FunctionType callType = _types.getCallType(_types.getThisType(cls));
+      if (callType != null) {
+        processSupertype(_closedWorld.commonElements.functionType);
+      }
+      return checks;
     }
+
+    for (ClassEntity cls in classUseMap.keys) {
+      ClassUse classUse = classUseMap[cls] ?? emptyUse;
+      if (classUse.instance || classUse.typeArgument) {
+        // Add checks only for classes that are live either as instantiated
+        // classes or type arguments passed at runtime.
+        computeChecks(cls);
+      }
+    }
+
     return result;
   }
 
@@ -318,11 +509,14 @@
     Set<ClassEntity> instantiated = new Set<ClassEntity>();
     ArgumentCollector collector = new ArgumentCollector();
     for (ClassEntity target in checks.classes) {
-      instantiated.add(target);
-      for (TypeCheck check in checks[target]) {
-        Substitution substitution = check.substitution;
-        if (substitution != null) {
-          collector.collectAll(substitution.arguments);
+      ClassChecks classChecks = checks[target];
+      if (classChecks.isNotEmpty) {
+        instantiated.add(target);
+        for (TypeCheck check in classChecks.checks) {
+          Substitution substitution = check.substitution;
+          if (substitution != null) {
+            collector.collectAll(substitution.arguments);
+          }
         }
       }
     }
@@ -371,7 +565,7 @@
   @override
   Substitution getSubstitution(ClassEntity cls, ClassEntity other) {
     // Look for a precomputed check.
-    for (TypeCheck check in _requiredChecks[cls]) {
+    for (TypeCheck check in _requiredChecks[cls].checks) {
       if (check.cls == other) {
         return check.substitution;
       }
@@ -400,17 +594,10 @@
 }
 
 class TrivialRuntimeTypesSubstitutions extends RuntimeTypesSubstitutionsMixin {
-  final ElementEnvironment _elementEnvironment;
-  final DartTypes _types;
+  final ClosedWorld _closedWorld;
   TypeChecks _requiredChecks;
 
-  TrivialRuntimeTypesSubstitutions(this._elementEnvironment, this._types);
-
-  @override
-  TypeChecks computeChecks(
-      Iterable<ClassEntity> instantiated, Iterable<ClassEntity> checked) {
-    return _requiredChecks;
-  }
+  TrivialRuntimeTypesSubstitutions(this._closedWorld);
 }
 
 /// Interface for computing substitutions need for runtime type checks.
@@ -419,11 +606,6 @@
 
   Substitution getSubstitution(ClassEntity cls, ClassEntity other);
 
-  /// Compute the required type checks and substitutions for the given
-  /// instantiated and checked classes.
-  TypeChecks computeChecks(
-      Iterable<ClassEntity> instantiated, Iterable<ClassEntity> checked);
-
   Set<ClassEntity> getClassesUsedInSubstitutions(TypeChecks checks);
 
   static bool hasTypeArguments(DartType type) {
@@ -1168,30 +1350,18 @@
 }
 
 class _RuntimeTypesChecks implements RuntimeTypesChecks {
-  final RuntimeTypesSubstitutions substitutions;
+  final RuntimeTypesSubstitutions _substitutions;
   final TypeChecks requiredChecks;
-  final Iterable<ClassEntity> directlyInstantiatedArguments;
-  final Iterable<ClassEntity> checkedArguments;
   final Iterable<ClassEntity> checkedClasses;
   final Iterable<FunctionType> checkedFunctionTypes;
-  final TypeVariableTests typeVariableTests;
+  final TypeVariableTests _typeVariableTests;
 
-  _RuntimeTypesChecks(
-      this.substitutions,
-      this.requiredChecks,
-      this.directlyInstantiatedArguments,
-      this.checkedArguments,
-      this.checkedClasses,
-      this.checkedFunctionTypes,
-      this.typeVariableTests);
+  _RuntimeTypesChecks(this._substitutions, this.requiredChecks,
+      this.checkedClasses, this.checkedFunctionTypes, this._typeVariableTests);
 
   @override
-  Iterable<ClassEntity> getRequiredArgumentClasses() {
-    Set<ClassEntity> requiredArgumentClasses = new Set<ClassEntity>.from(
-        substitutions.getClassesUsedInSubstitutions(requiredChecks));
-    return requiredArgumentClasses
-      ..addAll(directlyInstantiatedArguments)
-      ..addAll(checkedArguments);
+  Iterable<ClassEntity> get requiredClasses {
+    return _substitutions.getClassesUsedInSubstitutions(requiredChecks);
   }
 
   @override
@@ -1203,14 +1373,13 @@
 
   @override
   Iterable<ClassEntity> get classesUsingTypeVariableTests =>
-      typeVariableTests.classTests;
+      _typeVariableTests.classTests;
 }
 
 class RuntimeTypesImpl extends _RuntimeTypesBase
     with RuntimeTypesSubstitutionsMixin
     implements RuntimeTypesChecksBuilder {
-  final CommonElements _commentElements;
-  final ElementEnvironment _elementEnvironment;
+  final ClosedWorld _closedWorld;
 
   // The set of type arguments tested against type variable bounds.
   final Set<DartType> checkedTypeArguments = new Set<DartType>();
@@ -1221,16 +1390,15 @@
 
   bool rtiChecksBuilderClosed = false;
 
-  RuntimeTypesImpl(
-      this._commentElements, this._elementEnvironment, DartTypes types)
-      : super(types);
+  RuntimeTypesImpl(this._closedWorld) : super(_closedWorld.dartTypes);
+
+  CommonElements get _commonElements => _closedWorld.commonElements;
+  ElementEnvironment get _elementEnvironment => _closedWorld.elementEnvironment;
+  RuntimeTypesNeed get _rtiNeed => _closedWorld.rtiNeed;
 
   @override
   TypeChecks get _requiredChecks => cachedRequiredChecks;
 
-  Set<ClassEntity> directlyInstantiatedArguments;
-  Set<ClassEntity> allInstantiatedArguments;
-
   @override
   void registerTypeVariableBoundsSubtypeCheck(
       DartType typeArgument, DartType bound) {
@@ -1241,42 +1409,85 @@
   RuntimeTypesChecks computeRequiredChecks(
       CodegenWorldBuilder codegenWorldBuilder) {
     TypeVariableTests typeVariableTests = new TypeVariableTests(
-        _elementEnvironment, _commentElements, _types, codegenWorldBuilder);
+        _elementEnvironment, _commonElements, _types, codegenWorldBuilder);
     Set<DartType> explicitIsChecks = typeVariableTests.explicitIsChecks;
     Set<DartType> implicitIsChecks = typeVariableTests.implicitIsChecks;
 
+    Map<ClassEntity, ClassUse> classUseMap = <ClassEntity, ClassUse>{};
+
     Set<ClassEntity> checkedClasses = new Set<ClassEntity>();
     Set<FunctionType> checkedFunctionTypes = new Set<FunctionType>();
 
+    TypeVisitor liveTypeVisitor =
+        new TypeVisitor(onClass: (ClassEntity cls, {bool inTypeArgument}) {
+      ClassUse classUse = classUseMap.putIfAbsent(cls, () => new ClassUse());
+      if (inTypeArgument) {
+        classUse.typeArgument = true;
+      }
+    });
+
+    TypeVisitor testedTypeVisitor =
+        new TypeVisitor(onClass: (ClassEntity cls, {bool inTypeArgument}) {
+      ClassUse classUse = classUseMap.putIfAbsent(cls, () => new ClassUse());
+      if (inTypeArgument) {
+        classUse.typeArgument = true;
+        classUse.checkedTypeArgument = true;
+      } else {
+        classUse.checkedInstance = true;
+      }
+    });
+
     void processType(DartType t) {
       if (t is FunctionType) {
         checkedFunctionTypes.add(t);
       } else if (t is InterfaceType) {
         checkedClasses.add(t.element);
       }
+      testedTypeVisitor.visitType(t, false);
     }
 
+    codegenWorldBuilder.instantiatedTypes.forEach((t) {
+      liveTypeVisitor.visitType(t, false);
+      ClassUse classUse =
+          classUseMap.putIfAbsent(t.element, () => new ClassUse());
+      classUse.instance = true;
+    });
+    Set<FunctionType> instantiatedClosureTypes =
+        computeInstantiatedClosureTypes(codegenWorldBuilder);
+    instantiatedClosureTypes.forEach((t) {
+      testedTypeVisitor.visitType(t, false);
+    });
+
     explicitIsChecks.forEach(processType);
     implicitIsChecks.forEach(processType);
 
-    // These types are needed for is-checks against function types.
-    Set<DartType> instantiatedTypesAndClosures =
-        computeInstantiatedTypesAndClosures(codegenWorldBuilder);
-    computeInstantiatedArguments(
-        instantiatedTypesAndClosures, explicitIsChecks, implicitIsChecks);
-    Set<ClassEntity> checkedArguments = computeCheckedArguments(
-        instantiatedTypesAndClosures, explicitIsChecks, implicitIsChecks);
-    cachedRequiredChecks =
-        computeChecks(allInstantiatedArguments, checkedArguments);
+    cachedRequiredChecks = _computeChecks(classUseMap);
     rtiChecksBuilderClosed = true;
-    return new _RuntimeTypesChecks(
-        this,
-        cachedRequiredChecks,
-        directlyInstantiatedArguments,
-        checkedArguments,
-        checkedClasses,
-        checkedFunctionTypes,
-        typeVariableTests);
+    return new _RuntimeTypesChecks(this, cachedRequiredChecks, checkedClasses,
+        checkedFunctionTypes, typeVariableTests);
+  }
+
+  Set<FunctionType> computeInstantiatedClosureTypes(
+      CodegenWorldBuilder codegenWorldBuilder) {
+    Set<FunctionType> instantiatedClosureTypes = new Set<FunctionType>();
+    for (InterfaceType instantiatedType
+        in codegenWorldBuilder.instantiatedTypes) {
+      FunctionType callType = _types.getCallType(instantiatedType);
+      if (callType != null) {
+        instantiatedClosureTypes.add(callType);
+      }
+    }
+    for (FunctionEntity element
+        in codegenWorldBuilder.staticFunctionsNeedingGetter) {
+      instantiatedClosureTypes
+          .add(_elementEnvironment.getFunctionType(element));
+    }
+
+    for (FunctionEntity element in codegenWorldBuilder.closurizedMembers) {
+      instantiatedClosureTypes
+          .add(_elementEnvironment.getFunctionType(element));
+    }
+    return instantiatedClosureTypes;
   }
 
   Set<DartType> computeInstantiatedTypesAndClosures(
@@ -1300,99 +1511,6 @@
     }
     return instantiatedTypes;
   }
-
-  /**
-   * Collects all types used in type arguments of instantiated types.
-   *
-   * This includes type arguments used in supertype relations, because we may
-   * have a type check against this supertype that includes a check against
-   * the type arguments.
-   */
-  void computeInstantiatedArguments(Set<DartType> instantiatedTypes,
-      Set<DartType> isChecks, Set<DartType> implicitIsChecks) {
-    ArgumentCollector superCollector = new ArgumentCollector();
-    ArgumentCollector directCollector = new ArgumentCollector();
-    FunctionArgumentCollector functionArgumentCollector =
-        new FunctionArgumentCollector();
-
-    // We need to add classes occurring in function type arguments, like for
-    // instance 'I' for [: o is C<f> :] where f is [: typedef I f(); :].
-    void collectFunctionTypeArguments(Iterable<DartType> types) {
-      for (DartType type in types) {
-        functionArgumentCollector.collect(type);
-      }
-    }
-
-    collectFunctionTypeArguments(isChecks);
-    collectFunctionTypeArguments(implicitIsChecks);
-    collectFunctionTypeArguments(checkedBounds);
-
-    void collectTypeArguments(Iterable<DartType> types,
-        {bool isTypeArgument: false}) {
-      for (DartType type in types) {
-        directCollector.collect(type, isTypeArgument: isTypeArgument);
-        if (type is InterfaceType) {
-          ClassEntity cls = type.element;
-          for (InterfaceType supertype in _types.getSupertypes(cls)) {
-            superCollector.collect(supertype, isTypeArgument: isTypeArgument);
-          }
-        }
-      }
-    }
-
-    collectTypeArguments(instantiatedTypes);
-    collectTypeArguments(checkedTypeArguments, isTypeArgument: true);
-
-    for (ClassEntity cls in superCollector.classes.toList()) {
-      for (InterfaceType supertype in _types.getSupertypes(cls)) {
-        superCollector.collect(supertype);
-      }
-    }
-
-    directlyInstantiatedArguments = directCollector.classes
-      ..addAll(functionArgumentCollector.classes);
-    allInstantiatedArguments = superCollector.classes
-      ..addAll(directlyInstantiatedArguments);
-  }
-
-  /// Collects all type arguments used in is-checks.
-  Set<ClassEntity> computeCheckedArguments(Set<DartType> instantiatedTypes,
-      Set<DartType> isChecks, Set<DartType> implicitIsChecks) {
-    ArgumentCollector collector = new ArgumentCollector();
-    FunctionArgumentCollector functionArgumentCollector =
-        new FunctionArgumentCollector();
-
-    // We need to add types occurring in function type arguments, like for
-    // instance 'J' for [: (J j) {} is f :] where f is
-    // [: typedef void f(I i); :] and 'J' is a subtype of 'I'.
-    void collectFunctionTypeArguments(Iterable<DartType> types) {
-      for (DartType type in types) {
-        functionArgumentCollector.collect(type);
-      }
-    }
-
-    collectFunctionTypeArguments(instantiatedTypes);
-    collectFunctionTypeArguments(checkedTypeArguments);
-
-    void collectTypeArguments(Iterable<DartType> types,
-        {bool isTypeArgument: false}) {
-      for (DartType type in types) {
-        collector.collect(type, isTypeArgument: isTypeArgument);
-      }
-    }
-
-    collectTypeArguments(isChecks);
-    collectTypeArguments(implicitIsChecks);
-    collectTypeArguments(checkedBounds, isTypeArgument: true);
-
-    return collector.classes..addAll(functionArgumentCollector.classes);
-  }
-
-  @override
-  TypeChecks computeChecks(
-      Iterable<ClassEntity> instantiated, Iterable<ClassEntity> checked) {
-    return _computeChecks(instantiated, checked);
-  }
 }
 
 class RuntimeTypesEncoderImpl implements RuntimeTypesEncoder {
@@ -1509,6 +1627,10 @@
   @override
   jsAst.Expression getSubstitutionCode(
       Emitter emitter, Substitution substitution) {
+    if (substitution.isTrivial) {
+      return new jsAst.LiteralNull();
+    }
+
     jsAst.Expression declaration(TypeVariableType variable) {
       return new jsAst.Parameter(getVariableName(variable.element.name));
     }
@@ -1799,17 +1921,15 @@
 }
 
 class TypeCheckMapping implements TypeChecks {
-  final Map<ClassEntity, Set<TypeCheck>> map =
-      new Map<ClassEntity, Set<TypeCheck>>();
+  final Map<ClassEntity, ClassChecks> map = new Map<ClassEntity, ClassChecks>();
 
-  Iterable<TypeCheck> operator [](ClassEntity element) {
-    Set<TypeCheck> result = map[element];
-    return result != null ? result : const <TypeCheck>[];
+  ClassChecks operator [](ClassEntity element) {
+    ClassChecks result = map[element];
+    return result != null ? result : const ClassChecks.empty();
   }
 
-  void add(ClassEntity cls, ClassEntity check, Substitution substitution) {
-    map.putIfAbsent(cls, () => new Set<TypeCheck>());
-    map[cls].add(new TypeCheck(check, substitution));
+  void operator []=(ClassEntity element, ClassChecks checks) {
+    map[element] = checks;
   }
 
   Iterable<ClassEntity> get classes => map.keys;
@@ -1817,7 +1937,7 @@
   String toString() {
     StringBuffer sb = new StringBuffer();
     for (ClassEntity holder in classes) {
-      for (TypeCheck check in this[holder]) {
+      for (TypeCheck check in this[holder].checks) {
         sb.write('${holder.name} <: ${check.cls.name}, ');
       }
     }
@@ -1904,18 +2024,28 @@
 /// representation consult the documentation of [getSupertypeSubstitution].
 //TODO(floitsch): Remove support for non-function substitutions.
 class Substitution {
+  final bool isTrivial;
   final bool isFunction;
   final List<DartType> arguments;
   final List<DartType> parameters;
 
-  Substitution.list(this.arguments)
-      : isFunction = false,
+  const Substitution.trivial()
+      : isTrivial = true,
+        isFunction = false,
+        arguments = const <DartType>[],
         parameters = const <DartType>[];
 
-  Substitution.function(this.arguments, this.parameters) : isFunction = true;
+  Substitution.list(this.arguments)
+      : isTrivial = false,
+        isFunction = false,
+        parameters = const <DartType>[];
 
-  String toString() => 'Substitution(isFunction=$isFunction,'
-      'arguments=$arguments,parameters=$parameters)';
+  Substitution.function(this.arguments, this.parameters)
+      : isTrivial = false,
+        isFunction = true;
+
+  String toString() => 'Substitution(isTrivial=$isTrivial,'
+      'isFunction=$isFunction,arguments=$arguments,parameters=$parameters)';
 }
 
 /**
@@ -1924,11 +2054,148 @@
  */
 class TypeCheck {
   final ClassEntity cls;
+  final bool needsIs;
   final Substitution substitution;
   final int hashCode = _nextHash = (_nextHash + 100003).toUnsigned(30);
   static int _nextHash = 0;
 
-  TypeCheck(this.cls, this.substitution);
+  TypeCheck(this.cls, this.substitution, {this.needsIs: true});
 
-  String toString() => 'TypeCheck(cls=$cls,substitution=$substitution)';
+  String toString() =>
+      'TypeCheck(cls=$cls,needsIs=$needsIs,substitution=$substitution)';
+}
+
+class TypeVisitor extends ResolutionDartTypeVisitor<void, bool> {
+  final void Function(ClassEntity entity, {bool inTypeArgument}) onClass;
+  final void Function(TypeVariableEntity entity, {bool inTypeArgument})
+      onTypeVariable;
+  final void Function(FunctionType type, {bool inTypeArgument}) onFunctionType;
+
+  TypeVisitor({this.onClass, this.onTypeVariable, this.onFunctionType});
+
+  visitType(DartType type, bool inTypeArgument) =>
+      type.accept(this, inTypeArgument);
+
+  visitTypes(List<DartType> types, bool inTypeArgument) {
+    for (DartType type in types) {
+      visitType(type, inTypeArgument);
+    }
+  }
+
+  @override
+  void visitTypeVariableType(TypeVariableType type, bool inTypeArgument) {
+    if (onTypeVariable != null) {
+      onTypeVariable(type.element, inTypeArgument: inTypeArgument);
+    }
+  }
+
+  @override
+  visitInterfaceType(InterfaceType type, bool inTypeArgument) {
+    if (onClass != null) {
+      onClass(type.element, inTypeArgument: inTypeArgument);
+    }
+    visitTypes(type.typeArguments, true);
+  }
+
+  @override
+  visitFunctionType(FunctionType type, bool inTypeArgument) {
+    if (onFunctionType != null) {
+      onFunctionType(type, inTypeArgument: inTypeArgument);
+    }
+    // Visit all nested types as type arguments; these types are not runtime
+    // instances but runtime type representations.
+    visitType(type.returnType, true);
+    visitTypes(type.parameterTypes, true);
+    visitTypes(type.optionalParameterTypes, true);
+    visitTypes(type.namedParameterTypes, true);
+  }
+
+  @override
+  visitTypedefType(TypedefType type, bool inTypeArgument) {
+    visitType(type.unaliased, inTypeArgument);
+  }
+
+  @override
+  visitFunctionTypeVariable(FunctionTypeVariable type, bool inTypeArgument) {
+    visitType(type.bound, inTypeArgument);
+  }
+}
+
+/// [TypeCheck]s need for a single class.
+class ClassChecks {
+  final Map<ClassEntity, TypeCheck> _map;
+
+  ClassChecks() : _map = <ClassEntity, TypeCheck>{};
+
+  const ClassChecks.empty() : _map = const <ClassEntity, TypeCheck>{};
+
+  void add(TypeCheck check) {
+    _map[check.cls] = check;
+  }
+
+  TypeCheck operator [](ClassEntity cls) => _map[cls];
+
+  Iterable<TypeCheck> get checks => _map.values;
+
+  bool get isNotEmpty => _map.isNotEmpty;
+
+  String toString() {
+    return 'ClassChecks($checks)';
+  }
+}
+
+/// Runtime type usage for a class.
+class ClassUse {
+  /// Whether the class is instantiated.
+  ///
+  /// For instance `A` in:
+  ///
+  ///     class A {}
+  ///     main() => new A();
+  ///
+  bool instance = false;
+
+  /// Whether objects are checked to be instances of the class.
+  ///
+  /// For instance `A` in:
+  ///
+  ///     class A {}
+  ///     main() => null is A;
+  ///
+  bool checkedInstance = false;
+
+  /// Whether the class is passed as a type argument at runtime.
+  ///
+  /// For instance `A` in:
+  ///
+  ///     class A {}
+  ///     main() => new List<A>() is List<String>();
+  ///
+  bool typeArgument = false;
+
+  /// Whether the class is checked as a type argument at runtime.
+  ///
+  /// For instance `A` in:
+  ///
+  ///     class A {}
+  ///     main() => new List<String>() is List<A>();
+  ///
+  bool checkedTypeArgument = false;
+
+  String toString() {
+    List<String> properties = <String>[];
+    if (instance) {
+      properties.add('instance');
+    }
+    if (checkedInstance) {
+      properties.add('checkedInstance');
+    }
+    if (typeArgument) {
+      properties.add('typeArgument');
+    }
+    if (checkedTypeArgument) {
+      properties.add('checkedTypeArgument');
+    }
+    return 'ClassUse(${properties.join(',')})';
+  }
 }
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index d9cf761..cb3ae06 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -199,7 +199,6 @@
           backend.superMemberData,
           typeTestRegistry.rtiChecks,
           backend.rtiEncoder,
-          backend.rtiSubstitutions,
           backend.jsInteropAnalysis,
           backend.oneShotInterceptorData,
           backend.customElementsCodegenAnalysis,
diff --git a/pkg/compiler/lib/src/js_emitter/native_emitter.dart b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
index 70e3e35..12110ab 100644
--- a/pkg/compiler/lib/src/js_emitter/native_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
@@ -76,10 +76,8 @@
    * [classesModifiedByEmitRTISupport] contains the list of classes that must
    * exist, because runtime-type support adds information to the class.
    */
-  Set<Class> prepareNativeClasses(
-      List<Class> classes,
-      Set<ClassEntity> interceptorClassesNeededByConstants,
-      Set<ClassEntity> classesModifiedByEmitRTISupport) {
+  Set<Class> prepareNativeClasses(List<Class> classes,
+      Set<ClassEntity> interceptorClassesNeededByConstants) {
     assert(classes.every((Class cls) => cls != null));
 
     hasNativeClasses = classes.isNotEmpty;
@@ -136,10 +134,6 @@
         needed = true;
       } else if (interceptorClassesNeededByConstants.contains(classElement)) {
         needed = true;
-      } else if (classesModifiedByEmitRTISupport.contains(classElement)) {
-        // TODO(9556): Remove this test when [emitRuntimeTypeSupport] no longer
-        // adds information to a class prototype or constructor.
-        needed = true;
       } else if (extensionPoints.containsKey(cls)) {
         needed = true;
       }
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index 8b04d86..7877cdb 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -86,7 +86,7 @@
    * Return a function that returns true if its argument is a class
    * that needs to be emitted.
    */
-  Function computeClassFilter() {
+  Function computeClassFilter(Iterable<ClassEntity> backendTypeHelpers) {
     if (_mirrorsData.isTreeShakingDisabled) {
       return (ClassEntity cls) => true;
     }
@@ -117,16 +117,26 @@
     }
 
     // These classes are just helpers for the backend's type system.
-    unneededClasses.add(_commonElements.jsMutableArrayClass);
-    unneededClasses.add(_commonElements.jsFixedArrayClass);
-    unneededClasses.add(_commonElements.jsExtendableArrayClass);
-    unneededClasses.add(_commonElements.jsUInt32Class);
-    unneededClasses.add(_commonElements.jsUInt31Class);
-    unneededClasses.add(_commonElements.jsPositiveIntClass);
+    unneededClasses.addAll(backendTypeHelpers);
 
     return (ClassEntity cls) => !unneededClasses.contains(cls);
   }
 
+  // Return the classes that are just helpers for the backend's type system.
+  static Iterable<ClassEntity> getBackendTypeHelpers(
+      CommonElements commonElements) {
+    return <ClassEntity>[
+      commonElements.jsMutableArrayClass,
+      commonElements.jsFixedArrayClass,
+      commonElements.jsExtendableArrayClass,
+      // TODO(johnniwinther): Mark this as a backend type helper:
+      //commonElements.jsUnmodifiableArrayClass,
+      commonElements.jsUInt32Class,
+      commonElements.jsUInt31Class,
+      commonElements.jsPositiveIntClass
+    ];
+  }
+
   /**
    * Compute all the constants that must be emitted.
    */
@@ -193,6 +203,9 @@
 
   /// Compute all the classes and typedefs that must be emitted.
   void computeNeededDeclarations() {
+    Set<ClassEntity> backendTypeHelpers =
+        getBackendTypeHelpers(_commonElements).toSet();
+
     // Compute needed typedefs.
     typedefsNeededForReflection = _sorter.sortTypedefs(_closedWorld.allTypedefs
         .where(_mirrorsData.isTypedefAccessibleByReflection)
@@ -203,7 +216,7 @@
         // TODO(johnniwinther): This should be accessed from a codegen closed
         // world.
         _worldBuilder.directlyInstantiatedClasses
-            .where(computeClassFilter())
+            .where(computeClassFilter(backendTypeHelpers))
             .toSet();
 
     void addClassWithSuperclasses(ClassEntity cls) {
@@ -240,6 +253,7 @@
     // fields, etc.
     classesOnlyNeededForRti = new Set<ClassEntity>();
     for (ClassEntity cls in _rtiNeededClasses) {
+      if (backendTypeHelpers.contains(cls)) continue;
       while (cls != null && !neededClasses.contains(cls)) {
         if (!classesOnlyNeededForRti.add(cls)) break;
         cls = _elementEnvironment.getSuperClass(cls);
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index a6eb6fa..3a68f98 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -32,11 +32,7 @@
 import '../../js_backend/mirrors_data.dart';
 import '../../js_backend/js_interop_analysis.dart';
 import '../../js_backend/runtime_types.dart'
-    show
-        RuntimeTypesChecks,
-        RuntimeTypesNeed,
-        RuntimeTypesEncoder,
-        RuntimeTypesSubstitutions;
+    show RuntimeTypesChecks, RuntimeTypesNeed, RuntimeTypesEncoder;
 import '../../native/enqueue.dart' show NativeCodegenEnqueuer;
 import '../../options.dart';
 import '../../universe/selector.dart' show Selector;
@@ -82,7 +78,6 @@
   final SuperMemberData _superMemberData;
   final RuntimeTypesChecks _rtiChecks;
   final RuntimeTypesEncoder _rtiEncoder;
-  final RuntimeTypesSubstitutions _rtiSubstitutions;
   final JsInteropAnalysis _jsInteropAnalysis;
   final OneShotInterceptorData _oneShotInterceptorData;
   final CustomElementsCodegenAnalysis _customElementsCodegenAnalysis;
@@ -130,7 +125,6 @@
       this._superMemberData,
       this._rtiChecks,
       this._rtiEncoder,
-      this._rtiSubstitutions,
       this._jsInteropAnalysis,
       this._oneShotInterceptorData,
       this._customElementsCodegenAnalysis,
@@ -248,13 +242,9 @@
 
     Set<ClassEntity> interceptorClassesNeededByConstants =
         collector.computeInterceptorsReferencedFromConstants();
-    Set<ClassEntity> classesModifiedByEmitRTISupport =
-        _task.typeTestRegistry.computeClassesModifiedByEmitRuntimeTypeSupport();
 
     _unneededNativeClasses = _task.nativeEmitter.prepareNativeClasses(
-        nativeClasses,
-        interceptorClassesNeededByConstants,
-        classesModifiedByEmitRTISupport);
+        nativeClasses, interceptorClassesNeededByConstants);
 
     _addJsInteropStubs(_registry.mainLibrariesMap);
 
@@ -688,17 +678,12 @@
     RuntimeTypeGenerator runtimeTypeGenerator = new RuntimeTypeGenerator(
         _elementEnvironment,
         _commonElements,
-        _types,
-        _closedWorld,
         _closureDataLookup,
         _outputUnitData,
         _task,
         _namer,
-        _nativeData,
         _rtiChecks,
         _rtiEncoder,
-        _rtiNeed,
-        _rtiSubstitutions,
         _jsInteropAnalysis);
 
     void visitMember(MemberEntity member) {
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index 751aa63..bb68ca8 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -20,21 +20,17 @@
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
 import '../js_backend/js_interop_analysis.dart';
-import '../js_backend/native_data.dart';
 import '../js_backend/namer.dart' show Namer;
 import '../js_backend/runtime_types.dart'
     show
         RuntimeTypesChecks,
-        RuntimeTypesNeed,
         RuntimeTypesEncoder,
-        RuntimeTypesSubstitutions,
         Substitution,
         TypeCheck,
         TypeChecks;
 import '../js_emitter/sorter.dart';
 import '../js_model/closure.dart' show JClosureField;
 import '../util/util.dart' show Setlet;
-import '../world.dart';
 
 import 'code_emitter_task.dart' show CodeEmitterTask;
 import 'type_test_registry.dart' show TypeTestRegistry;
@@ -43,8 +39,6 @@
 typedef void FunctionTypeSignatureEmitter(
     FunctionEntity method, FunctionType methodType);
 
-typedef void SubstitutionEmitter(ClassEntity element, {bool emitNull});
-
 class TypeTest {
   final jsAst.Name name;
   final jsAst.Node expression;
@@ -108,33 +102,23 @@
 class RuntimeTypeGenerator {
   final ElementEnvironment _elementEnvironment;
   final CommonElements _commonElements;
-  final DartTypes _types;
-  final ClosedWorld _closedWorld;
   final ClosureConversionTask _closureDataLookup;
   final OutputUnitData _outputUnitData;
   final CodeEmitterTask emitterTask;
   final Namer _namer;
-  final NativeData _nativeData;
   final RuntimeTypesChecks _rtiChecks;
   final RuntimeTypesEncoder _rtiEncoder;
-  final RuntimeTypesNeed _rtiNeed;
-  final RuntimeTypesSubstitutions _rtiSubstitutions;
   final JsInteropAnalysis _jsInteropAnalysis;
 
   RuntimeTypeGenerator(
       this._elementEnvironment,
       this._commonElements,
-      this._types,
-      this._closedWorld,
       this._closureDataLookup,
       this._outputUnitData,
       this.emitterTask,
       this._namer,
-      this._nativeData,
       this._rtiChecks,
       this._rtiEncoder,
-      this._rtiNeed,
-      this._rtiSubstitutions,
       this._jsInteropAnalysis);
 
   TypeTestRegistry get _typeTestRegistry => emitterTask.typeTestRegistry;
@@ -165,18 +149,7 @@
     assert(!(classElement is ClassElement && !classElement.isDeclaration),
         failedAt(classElement));
 
-    /// Generates an is-test if the test is not inherited from a superclass
-    /// This assumes that for every class an is-tests is generated
-    /// dynamically at runtime. We also always generate tests against
-    /// native classes.
-    /// TODO(herhut): Generate tests for native classes dynamically, as well.
-    void generateIsTest(ClassEntity other) {
-      if (_nativeData.isNativeClass(classElement) ||
-          !_closedWorld.isSubclassOf(classElement, other)) {
-        result.addIsTest(other, _namer.operatorIs(other), js('1'));
-      }
-    }
-
+    // TODO(johnniwinther): Include function signatures in [ClassChecks].
     void generateFunctionTypeSignature(
         FunctionEntity method, FunctionType type) {
       assert(!(method is MethodElement && !method.isImplementation));
@@ -207,28 +180,12 @@
       }
     }
 
-    void generateSubstitution(ClassEntity cls, {bool emitNull: false}) {
-      if (!_elementEnvironment.isGenericClass(cls)) return;
-      jsAst.Expression expression;
-      bool needsNativeCheck =
-          emitterTask.nativeEmitter.requiresNativeIsCheck(cls);
-      Substitution substitution =
-          _rtiSubstitutions.getSubstitution(classElement, cls);
-      if (substitution != null) {
-        expression =
-            _rtiEncoder.getSubstitutionCode(emitterTask.emitter, substitution);
-      }
-      if (expression == null && (emitNull || needsNativeCheck)) {
-        expression = new jsAst.LiteralNull();
-      }
-      if (expression != null) {
-        result.addSubstitution(cls, _namer.substitutionName(cls), expression);
-      }
-    }
-
     void generateTypeCheck(TypeCheck check) {
       ClassEntity checkedClass = check.cls;
-      generateIsTest(checkedClass);
+      if (check.needsIs) {
+        result.addIsTest(
+            checkedClass, _namer.operatorIs(checkedClass), js('1'));
+      }
       Substitution substitution = check.substitution;
       if (substitution != null) {
         jsAst.Expression body =
@@ -239,12 +196,7 @@
     }
 
     _generateIsTestsOn(
-        classElement,
-        generateIsTest,
-        generateFunctionTypeSignature,
-        (ClassEntity e, {bool emitNull: false}) =>
-            generateSubstitution(e, emitNull: emitNull),
-        generateTypeCheck);
+        classElement, generateFunctionTypeSignature, generateTypeCheck);
 
     if (classElement == _commonElements.jsJavaScriptFunctionClass) {
       var type = _jsInteropAnalysis.buildJsFunctionType();
@@ -268,21 +220,13 @@
    */
   void _generateIsTestsOn(
       ClassEntity cls,
-      void generateIsTest(ClassEntity element),
       FunctionTypeSignatureEmitter generateFunctionTypeSignature,
-      SubstitutionEmitter generateSubstitution,
       void emitTypeCheck(TypeCheck check)) {
     Setlet<ClassEntity> generated = new Setlet<ClassEntity>();
 
-    if (checkedClasses.contains(cls)) {
-      generateIsTest(cls);
-      generateSubstitution(cls);
-      generated.add(cls);
-    }
-
     // Precomputed is checks.
     TypeChecks typeChecks = _rtiChecks.requiredChecks;
-    Iterable<TypeCheck> classChecks = typeChecks[cls];
+    Iterable<TypeCheck> classChecks = typeChecks[cls].checks;
     if (classChecks != null) {
       for (TypeCheck check in classChecks) {
         if (!generated.contains(check.cls)) {
@@ -292,59 +236,6 @@
       }
     }
 
-    ClassEntity superclass = _elementEnvironment.getSuperClass(cls);
-
-    bool haveSameTypeVariables(ClassEntity a, ClassEntity b) {
-      if (a.isClosure) return true;
-      return _rtiSubstitutions.isTrivialSubstitution(a, b);
-    }
-
-    bool supertypesNeedSubstitutions = false;
-
-    if (superclass != null &&
-        superclass != _commonElements.objectClass &&
-        !haveSameTypeVariables(cls, superclass)) {
-      // We cannot inherit the generated substitutions, because the type
-      // variable layout for this class is different.  Instead we generate
-      // substitutions for all checks and make emitSubstitution a NOP for the
-      // rest of this function.
-
-      // TODO(karlklose): move the computation of these checks to
-      // RuntimeTypeInformation.
-      while (superclass != null) {
-        if (_rtiNeed.classNeedsTypeArguments(superclass)) {
-          generateSubstitution(superclass, emitNull: true);
-          generated.add(superclass);
-        }
-        superclass = _elementEnvironment.getSuperClass(superclass);
-      }
-      supertypesNeedSubstitutions = true;
-    }
-
-    if (_elementEnvironment.isMixinApplication(cls)) {
-      supertypesNeedSubstitutions = true;
-    }
-
-    if (supertypesNeedSubstitutions) {
-      _elementEnvironment.forEachSupertype(cls, (InterfaceType supertype) {
-        ClassEntity superclass = supertype.element;
-        if (generated.contains(superclass)) return;
-
-        if (classesUsingTypeVariableTests.contains(superclass) ||
-            _rtiNeed.classUsesTypeVariableLiteral(superclass) ||
-            checkedClasses.contains(superclass)) {
-          // Generate substitution.  If no substitution is necessary, emit
-          // `null` to overwrite a (possibly) existing substitution from the
-          // super classes.
-          generateSubstitution(superclass, emitNull: true);
-        }
-      });
-
-      void emitNothing(_, {emitNull}) {}
-
-      generateSubstitution = emitNothing;
-    }
-
     // A class that defines a `call` method implicitly implements
     // [Function] and needs checks for all typedefs that are used in is-checks.
     if (checkedClasses.contains(_commonElements.functionClass) ||
@@ -353,57 +244,10 @@
           _elementEnvironment.lookupLocalClassMember(cls, Identifiers.call);
       if (call != null && call.isFunction) {
         FunctionEntity callFunction = call;
-        // A superclass might already implement the Function interface. In such
-        // a case, we can avoid emitting the is test here.
-        ClassEntity superclass = _elementEnvironment.getSuperClass(cls);
-        if (!_closedWorld.isSubtypeOf(
-            superclass, _commonElements.functionClass)) {
-          _generateInterfacesIsTests(_commonElements.functionClass,
-              generateIsTest, generateSubstitution, generated);
-        }
         FunctionType callType =
             _elementEnvironment.getFunctionType(callFunction);
         generateFunctionTypeSignature(callFunction, callType);
       }
     }
-
-    for (InterfaceType interfaceType in _types.getInterfaces(cls)) {
-      _generateInterfacesIsTests(interfaceType.element, generateIsTest,
-          generateSubstitution, generated);
-    }
-  }
-
-  /**
-   * Generate "is tests" where [cls] is being implemented.
-   */
-  void _generateInterfacesIsTests(
-      ClassEntity cls,
-      void generateIsTest(ClassEntity element),
-      SubstitutionEmitter generateSubstitution,
-      Set<ClassEntity> alreadyGenerated) {
-    void tryEmitTest(ClassEntity check) {
-      if (!alreadyGenerated.contains(check) && checkedClasses.contains(check)) {
-        alreadyGenerated.add(check);
-        generateIsTest(check);
-        generateSubstitution(check);
-      }
-    }
-
-    tryEmitTest(cls);
-
-    for (InterfaceType interfaceType in _types.getInterfaces(cls)) {
-      ClassEntity element = interfaceType.element;
-      tryEmitTest(element);
-      _generateInterfacesIsTests(
-          element, generateIsTest, generateSubstitution, alreadyGenerated);
-    }
-
-    // We need to also emit "is checks" for the superclass and its supertypes.
-    ClassEntity superclass = _elementEnvironment.getSuperClass(cls);
-    if (superclass != null) {
-      tryEmitTest(superclass);
-      _generateInterfacesIsTests(
-          superclass, generateIsTest, generateSubstitution, alreadyGenerated);
-    }
   }
 }
diff --git a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
index 0e31b7c..a740fb0 100644
--- a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
+++ b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
@@ -12,8 +12,7 @@
     show
         RuntimeTypesChecks,
         RuntimeTypesChecksBuilder,
-        RuntimeTypesSubstitutions,
-        TypeChecks;
+        RuntimeTypesSubstitutions;
 import '../js_backend/mirrors_data.dart';
 import '../universe/world_builder.dart';
 import '../world.dart' show ClosedWorld;
@@ -49,22 +48,6 @@
     return _rtiNeededClasses;
   }
 
-  /**
-   * Returns the classes with constructors used as a 'holder' in
-   * [emitRuntimeTypeSupport].
-   * TODO(9556): Some cases will go away when the class objects are created as
-   * complete.  Not all classes will go away while constructors are referenced
-   * from type substitutions.
-   */
-  Set<ClassEntity> computeClassesModifiedByEmitRuntimeTypeSupport() {
-    TypeChecks typeChecks = rtiChecks.requiredChecks;
-    Set<ClassEntity> result = new Set<ClassEntity>();
-    for (ClassEntity cls in typeChecks.classes) {
-      if (typeChecks[cls].isNotEmpty) result.add(cls);
-    }
-    return result;
-  }
-
   void computeRtiNeededClasses(RuntimeTypesSubstitutions rtiSubstitutions,
       MirrorsData mirrorsData, Iterable<MemberEntity> liveMembers) {
     _rtiNeededClasses = new Set<ClassEntity>();
@@ -86,19 +69,9 @@
 
     // 1.  Add classes that are referenced by type arguments or substitutions in
     //     argument checks.
-    // TODO(karlklose): merge this case with 2 when unifying argument and
-    // object checks.
-    rtiChecks
-        .getRequiredArgumentClasses()
-        .forEach((e) => addClassWithSuperclasses(e));
+    addClassesWithSuperclasses(rtiChecks.requiredClasses);
 
-    // 2.  Add classes that are referenced by substitutions in object checks and
-    //     their superclasses.
-    Set<ClassEntity> classesUsedInSubstitutions = rtiSubstitutions
-        .getClassesUsedInSubstitutions(rtiChecks.requiredChecks);
-    addClassesWithSuperclasses(classesUsedInSubstitutions);
-
-    // 3.  Add classes that contain checked generic function types. These are
+    // 2.  Add classes that contain checked generic function types. These are
     //     needed to store the signature encoding.
     for (FunctionType type in rtiChecks.checkedFunctionTypes) {
       ClassEntity contextClass = DartTypes.getClassContext(type);
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 30d7a36..ab6b21e 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -260,6 +260,10 @@
     _memberClosureRepresentationMap[closureClassInfo.signatureMethod] =
         closureClassInfo;
     _globalLocalsMap.setLocalsMap(closureClassInfo.callMethod, localsMap);
+    if (_strongMode) {
+      _globalLocalsMap.setLocalsMap(
+          closureClassInfo.signatureMethod, localsMap);
+    }
     if (node.parent is ir.Member) {
       assert(_elementMap.getMember(node.parent) == member);
       _memberClosureRepresentationMap[member] = closureClassInfo;
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 7c42e2c..9d4b34a 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -900,7 +900,7 @@
   /// that no corresponding ir.Node actually exists for it. We just use the
   /// targetElement.
   void buildMethodSignature(ir.FunctionNode originalClosureNode) {
-    openFunction(targetElement);
+    openFunction(targetElement, originalClosureNode);
     List<HInstruction> typeArguments = <HInstruction>[];
 
     // Add function type variables.
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
new file mode 100755
index 0000000..4bead5f
--- /dev/null
+++ b/pkg/dev_compiler/tool/ddb
@@ -0,0 +1,209 @@
+#!/usr/bin/env dart
+// 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.
+
+//
+// Compiles code with DDC and runs the resulting code with either node or
+// chrome.
+//
+// The first script supplied should be the one with `main()`.
+//
+// Saves the output in the same directory as the sources for convenient
+// inspection, modification or rerunning the code.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:args/args.dart' show ArgParser;
+import 'package:path/path.dart' as path;
+
+void main(List<String> args) {
+  // Parse flags.
+  var parser = new ArgParser()
+    ..addFlag('kernel',
+        abbr: 'k', help: 'Compile with the new kernel-based front end.')
+    ..addFlag('debug',
+        abbr: 'd',
+        help: 'Use current source instead of built SDK.',
+        defaultsTo: false)
+    ..addOption('runtime',
+        abbr: 'r',
+        help: 'Platform to run on (node|d8|chrome).  Default is node.',
+        allowed: ['node', 'd8', 'chrome'],
+        defaultsTo: 'node')
+    ..addOption('binary', abbr: 'b', help: 'Runtime binary path.');
+
+  var options = parser.parse(args);
+  if (options.rest.length != 1) {
+    throw 'Expected a single dart entrypoint.';
+  }
+  var entry = options.rest.first;
+  var libRoot = path.dirname(entry);
+  var basename = path.basenameWithoutExtension(entry);
+
+  var debug = options['debug'] as bool;
+  var kernel = options['kernel'] as bool;
+  var binary = options['binary'] as String;
+
+  var dartBinary = Platform.resolvedExecutable;
+  var dartPath = path.dirname(dartBinary);
+  var dartSdk = path.dirname(dartPath);
+  var toolPath = Platform.script.normalizePath().toFilePath();
+  var ddcPath = path.dirname(path.dirname(toolPath));
+
+  ProcessResult runDdc(String command, List<String> args) {
+    if (debug) {
+      // Use unbuilt script.  This only works from a source checkout.
+      args.insertAll(0, ['-c', path.join(ddcPath, 'bin', '${command}.dart')]);
+      command = dartBinary;
+    } else {
+      // Use built snapshot.
+      command = path.join(dartPath, command);
+    }
+    return Process.runSync(command, args);
+  }
+
+  String mod;
+  bool chrome = false;
+  bool node = false;
+  bool d8 = false;
+  switch (options['runtime']) {
+    case 'node':
+      node = true;
+      mod = 'common';
+      break;
+    case 'd8':
+      d8 = true;
+      mod = 'es6';
+      break;
+    case 'chrome':
+      chrome = true;
+      mod = 'amd';
+      break;
+  }
+  var sdkJsPath = path.join(dartSdk, 'lib', 'dev_compiler', mod);
+
+  ProcessResult result;
+  if (kernel) {
+    var ddcSdk = path.join(dartSdk, 'lib', '_internal', 'ddc_sdk.dill');
+    result = runDdc('dartdevk', [
+      '--modules=$mod',
+      '--dart-sdk-summary=$ddcSdk',
+      '-o',
+      '$basename.js',
+      entry
+    ]);
+  } else {
+    result = runDdc('dartdevc', [
+      '--modules=$mod',
+      '--library-root=$libRoot',
+      '-o',
+      '$basename.js',
+      entry
+    ]);
+  }
+
+  print(result.stdout);
+  if (result.exitCode != 0) {
+    print(result.stderr);
+    exit(result.exitCode);
+  }
+
+  if (chrome) {
+    String chromeBinary;
+    if (binary != null) {
+      chromeBinary = binary;
+    } else if (Platform.isWindows) {
+      chromeBinary =
+          'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe';
+    } else if (Platform.isMacOS) {
+      chromeBinary =
+          '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
+    } else {
+      // Assume Linux
+      chromeBinary = 'google-chrome';
+    }
+
+    var html = """
+<script src='$sdkJsPath/require.js'></script>
+<script>
+  require.config({
+    baseUrl: '$libRoot',
+    paths: {
+        'dart_sdk': '$sdkJsPath/dart_sdk'
+    },
+    waitSeconds: 15
+  });
+  require(['dart_sdk', '$basename'],
+        function(sdk, app) {
+    'use strict';
+    sdk._debugger.registerDevtoolsFormatter();
+    sdk.dart.ignoreWhitelistedErrors(false);
+    sdk._isolate_helper.startRootIsolate(() => {}, []);
+    app.$basename.main();
+  });
+</script>
+""";
+    var htmlFile = '$libRoot/$basename.html';
+    new File(htmlFile).writeAsStringSync(html);
+    var tmp = path.join(Directory.systemTemp.path, 'ddc');
+
+    result = Process.runSync(chromeBinary,
+        ['--auto-open-devtools-for-tabs', '--user-data-dir=$tmp', htmlFile]);
+  } else if (node) {
+    var nodePath = '$sdkJsPath:$libRoot';
+    var runjs = '''
+    let source_maps;
+    try {
+      source_maps = require('source-map-support');
+      source_maps.install();
+    } catch(e) {
+    }
+    let sdk = require(\"dart_sdk\");
+    let main = require(\"./$basename\").$basename.main;
+    sdk.dart.ignoreWhitelistedErrors(false);
+    try {
+      sdk._isolate_helper.startRootIsolate(main, []);
+    } catch(e) {
+      if (!source_maps) {
+        console.log('For Dart source maps: npm install source-map-support');
+      }
+      console.error(e.toString(), sdk.dart.stackTrace(e).toString());
+      process.exit(1);
+    }
+    ''';
+    var nodeFile = '$libRoot/$basename.run.js';
+    new File(nodeFile).writeAsStringSync(runjs);
+    var nodeBinary = binary ?? 'node';
+    result = Process
+        .runSync(nodeBinary, [nodeFile], environment: {'NODE_PATH': nodePath});
+    stdout
+      ..write(result.stdout)
+      ..flush();
+  } else if (d8) {
+    var runjs = '''
+    import { dart, _isolate_helper } from '$sdkJsPath/dart_sdk.js';
+    import { $basename } from '$basename.js';
+    let main = $basename.main;
+    dart.ignoreWhitelistedErrors(false);
+    try {
+      _isolate_helper.startRootIsolate(() => {}, []);
+      main();
+    } catch(e) {
+      console.error(e.toString(), dart.stackTrace(e).toString());
+    }
+    ''';
+    var d8File = '$libRoot/$basename.d8.js';
+    new File(d8File).writeAsStringSync(runjs);
+    var d8Binary = binary ?? 'd8';
+    result = Process.runSync(binary, ['--module', d8File]);
+    stdout
+      ..write(result.stdout)
+      ..flush();
+  }
+  if (result.exitCode != 0) {
+    print(result.stderr);
+    exit(result.exitCode);
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 2c46b7b..9f07a92 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -3289,64 +3289,81 @@
   Token parseInitializer(Token token) {
     Token next = token.next;
     listener.beginInitializer(next);
+    Token beforeExpression = token;
     if (optional('assert', next)) {
       token = parseAssert(token, Assert.Initializer);
+      listener.endInitializer(token.next);
+      return token;
     } else if (optional('super', next)) {
-      token = parseExpression(token);
+      return parseInitializerExpressionRest(token);
     } else if (optional('this', next)) {
-      if (!optional('(', next.next)) {
-        if (!optional('.', next.next)) {
+      token = next;
+      next = token.next;
+      if (optional('.', next)) {
+        token = next;
+        next = token.next;
+        if (next.isIdentifier) {
+          token = next;
+        } else {
           // Recovery
-          reportRecoverableError(
-              next.next, fasta.templateExpectedButGot.withArguments('.'));
-          rewriter.insertTokenAfter(
-              next, new SyntheticToken(TokenType.PERIOD, next.next.offset));
+          token = insertSyntheticIdentifier(
+              token, IdentifierContext.fieldInitializer);
         }
-        next = next.next;
-        if (!next.next.isIdentifier) {
-          // Recovery
-          insertSyntheticIdentifier(next, IdentifierContext.fieldInitializer);
+        next = token.next;
+        if (optional('=', next)) {
+          return parseInitializerExpressionRest(beforeExpression);
         }
-        next = next.next;
       }
-      if (optional('(', next.next)) {
-        token = parseExpression(token);
+      if (optional('(', next)) {
+        token = parseInitializerExpressionRest(beforeExpression);
         next = token.next;
         if (optional('{', next) || optional('=>', next)) {
           reportRecoverableError(
               next, fasta.messageRedirectingConstructorWithBody);
         }
-      } else {
-        if (!optional('=', next.next)) {
-          // Recovery
-          reportRecoverableError(
-              token.next, fasta.messageMissingAssignmentInInitializer);
-          next = rewriter
-              .insertTokenAfter(
-                  next, new SyntheticToken(TokenType.EQ, next.next.offset))
-              .next;
-          rewriter.insertTokenAfter(next,
-              new SyntheticStringToken(TokenType.IDENTIFIER, '', next.offset));
-        }
-        token = parseExpression(token);
+        return token;
       }
-    } else if (next.isIdentifier) {
-      if (!optional('=', next.next)) {
-        // Recovery
-        next = insertSyntheticIdentifier(
-            token, IdentifierContext.fieldInitializer,
-            message: fasta.messageMissingAssignmentInInitializer,
-            messageOnToken: next);
+      // Recovery
+      if (optional('this', token)) {
+        // TODO(danrubel): Consider a better error message indicating that
+        // `this.<fieldname>=` is expected.
+        reportRecoverableError(
+            next, fasta.templateExpectedButGot.withArguments('.'));
         rewriter.insertTokenAfter(
-            next, new SyntheticToken(TokenType.EQ, next.offset));
+            token, new SyntheticToken(TokenType.PERIOD, next.offset));
+        token = token.next;
+        rewriter.insertTokenAfter(token,
+            new SyntheticStringToken(TokenType.IDENTIFIER, '', next.offset));
+        token = token.next;
+        next = token.next;
       }
-      token = parseExpression(token);
+      // Fall through to recovery
+    } else if (next.isIdentifier) {
+      if (optional('=', next.next)) {
+        return parseInitializerExpressionRest(token);
+      }
+      // Fall through to recovery
     } else {
       // Recovery
       insertSyntheticIdentifier(token, IdentifierContext.fieldInitializer,
           message: fasta.messageExpectedAnInitializer, messageOnToken: token);
-      token = parseExpression(token);
+      return parseInitializerExpressionRest(beforeExpression);
     }
+    // Recovery
+    // Insert a sythetic assignment to ensure that the expression is indeed
+    // an assignment. Failing to do so causes this test to fail:
+    // pkg/front_end/testcases/regress/issue_31192.dart
+    // TODO(danrubel): Investigate better recovery.
+    token = insertSyntheticIdentifier(
+        beforeExpression, IdentifierContext.fieldInitializer,
+        message: fasta.messageMissingAssignmentInInitializer);
+    rewriter.insertTokenAfter(
+        token, new SyntheticToken(TokenType.EQ, token.offset));
+    return parseInitializerExpressionRest(beforeExpression);
+  }
+
+  Token parseInitializerExpressionRest(Token token) {
+    token = parseExpression(token);
     listener.endInitializer(token.next);
     return token;
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.md b/pkg/front_end/lib/src/fasta/parser/parser.md
index bf4999c..acbc13e 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.md
+++ b/pkg/front_end/lib/src/fasta/parser/parser.md
@@ -12,8 +12,6 @@
   * In parseSwitchCase, the parser uses peekPastLabels to select between case
     labels and statement labels.
 
-  * The parser uses isGeneralizedFunctionType in parseType, and findMemberName.
-
-  * The parser uses findMemberName in parseTopLevelMember, and parseMember.
+  * The parser uses isGeneralizedFunctionType in parseType.
 
   * The parser uses isValidMethodTypeArguments in parseSend.
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 375def5..ab381f5 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -216,10 +216,17 @@
     if (!dottedName.startsWith(prefix)) return "";
     dottedName = dottedName.substring(prefix.length);
 
-    LibraryBuilder coreLibrary =
-        loader.read(resolve(this.uri, "dart:core", -1), -1);
     LibraryBuilder imported =
-        coreLibrary.loader.builders[new Uri(scheme: 'dart', path: dottedName)];
+        loader.builders[new Uri(scheme: "dart", path: dottedName)];
+
+    if (imported == null) {
+      LibraryBuilder coreLibrary = loader.read(
+          resolve(
+              this.uri, new Uri(scheme: "dart", path: "core").toString(), -1),
+          -1);
+      imported = coreLibrary
+          .loader.builders[new Uri(scheme: 'dart', path: dottedName)];
+    }
     return imported != null ? "true" : "";
   }
 
diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart
index 8f8133e..72a0d20 100644
--- a/pkg/kernel/lib/transformations/async.dart
+++ b/pkg/kernel/lib/transformations/async.dart
@@ -413,16 +413,31 @@
     // The statements are in reverse order, so name the result first if
     // necessary and then add the two other statements in reverse.
     if (shouldName) result = name(result);
-    statements.add(R.createContinuationPoint()..fileOffset = expr.fileOffset);
     Arguments arguments = new Arguments(<Expression>[
       expr.operand,
       new VariableGet(R.thenContinuationVariable),
       new VariableGet(R.catchErrorContinuationVariable),
       new VariableGet(R.nestedClosureVariable),
     ]);
-    statements.add(new ExpressionStatement(
-        new StaticInvocation(R.helper.awaitHelper, arguments)
-          ..fileOffset = expr.fileOffset));
+
+    // We are building
+    //
+    //     [yield] (let _ = _awaitHelper(...) in null)
+    //
+    // to ensure that :await_jump_var and :await_jump_ctx are updated
+    // before _awaitHelper is invoked (see BuildYieldStatement in
+    // StreamingFlowGraphBuilder for details of how [yield] is translated to
+    // IL). This guarantees that recursive invocation of the current function
+    // would continue from the correct "jump" position. Recursive invocations
+    // arise if future we are awaiting completes synchronously. Builtin Future
+    // implementation don't complete synchronously, but Flutter's
+    // SynchronousFuture do (see bug http://dartbug.com/32098 for more details).
+    statements.add(R.createContinuationPoint(new Let(
+        new VariableDeclaration(null,
+            initializer: new StaticInvocation(R.helper.awaitHelper, arguments)
+              ..fileOffset = expr.fileOffset),
+        new NullLiteral()))
+      ..fileOffset = expr.fileOffset);
 
     seenAwait = false;
     var index = nameIndex;
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index 9d8e50e..d6ff80f 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -27,6 +27,13 @@
   return rewriter.rewriteProgram(program);
 }
 
+Procedure transformProcedure(
+    CoreTypes coreTypes, Procedure procedure, bool syncAsync) {
+  var helper = new HelperNodes.fromCoreTypes(coreTypes);
+  var rewriter = new RecursiveContinuationRewriter(helper, syncAsync);
+  return rewriter.visitProcedure(procedure);
+}
+
 class RecursiveContinuationRewriter extends Transformer {
   final HelperNodes helper;
 
diff --git a/runtime/bin/platform_fuchsia.cc b/runtime/bin/platform_fuchsia.cc
index d0277e0..24936b7 100644
--- a/runtime/bin/platform_fuchsia.cc
+++ b/runtime/bin/platform_fuchsia.cc
@@ -150,14 +150,12 @@
   exit(exit_code);
 }
 
-bool Platform::SaveConsoleConfiguration() {
+void Platform::SaveConsoleConfiguration() {
   UNIMPLEMENTED();
-  return false;
 }
 
-bool Platform::RestoreConsoleConfiguration() {
+void Platform::RestoreConsoleConfiguration() {
   UNIMPLEMENTED();
-  return false;
 }
 
 }  // namespace bin
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 3b57ef0..3a95a1a 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -3019,16 +3019,12 @@
                    intptr_t type_args_len,
                    const Array& argument_names,
                    PushArgumentsArray* arguments,
-                   TokenPosition token_pos,
-                   intptr_t argument_check_bits = 0,
-                   intptr_t type_argument_check_bits = 0)
+                   TokenPosition token_pos)
       : TemplateDefinition<kInputCount, Throws>(deopt_id),
         type_args_len_(type_args_len),
         argument_names_(argument_names),
         arguments_(arguments),
-        token_pos_(token_pos),
-        argument_check_bits_(argument_check_bits),
-        type_argument_check_bits_(type_argument_check_bits) {
+        token_pos_(token_pos) {
     ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap());
   }
 
@@ -3047,13 +3043,7 @@
   virtual TokenPosition token_pos() const { return token_pos_; }
   RawArray* GetArgumentsDescriptor() const {
     return ArgumentsDescriptor::New(
-        type_args_len(), ArgumentCountWithoutTypeArgs(), argument_names(),
-        argument_check_bits(), type_argument_check_bits());
-  }
-
-  intptr_t argument_check_bits() const { return argument_check_bits_; }
-  intptr_t type_argument_check_bits() const {
-    return type_argument_check_bits_;
+        type_args_len(), ArgumentCountWithoutTypeArgs(), argument_names());
   }
 
  private:
@@ -3062,12 +3052,6 @@
   PushArgumentsArray* arguments_;
   TokenPosition token_pos_;
 
-  // One bit per argument (up to word size) which helps the callee decide which
-  // arguments it needs to check. See the comments in ArgumentsDescriptor for
-  // more information on strong-mode checked calls.
-  intptr_t argument_check_bits_;
-  intptr_t type_argument_check_bits_;
-
   DISALLOW_COPY_AND_ASSIGN(TemplateDartCall);
 };
 
@@ -3128,16 +3112,12 @@
       intptr_t checked_argument_count,
       const ZoneGrowableArray<const ICData*>& ic_data_array,
       intptr_t deopt_id,
-      const Function& interface_target = Function::null_function(),
-      intptr_t argument_check_bits = 0,
-      intptr_t type_argument_check_bits = 0)
+      const Function& interface_target = Function::null_function())
       : TemplateDartCall(deopt_id,
                          type_args_len,
                          argument_names,
                          arguments,
-                         token_pos,
-                         argument_check_bits,
-                         type_argument_check_bits),
+                         token_pos),
         ic_data_(NULL),
         function_name_(function_name),
         token_kind_(token_kind),
@@ -3168,16 +3148,12 @@
       const Array& argument_names,
       intptr_t checked_argument_count,
       intptr_t deopt_id,
-      const Function& interface_target = Function::null_function(),
-      intptr_t argument_check_bits = 0,
-      intptr_t type_argument_check_bits = 0)
+      const Function& interface_target = Function::null_function())
       : TemplateDartCall(deopt_id,
                          type_args_len,
                          argument_names,
                          arguments,
-                         token_pos,
-                         argument_check_bits,
-                         type_argument_check_bits),
+                         token_pos),
         ic_data_(NULL),
         function_name_(function_name),
         token_kind_(token_kind),
@@ -3638,16 +3614,12 @@
                   PushArgumentsArray* arguments,
                   const ZoneGrowableArray<const ICData*>& ic_data_array,
                   intptr_t deopt_id,
-                  ICData::RebindRule rebind_rule,
-                  intptr_t argument_check_bits = 0,
-                  intptr_t type_argument_check_bits = 0)
+                  ICData::RebindRule rebind_rule)
       : TemplateDartCall(deopt_id,
                          type_args_len,
                          argument_names,
                          arguments,
-                         token_pos,
-                         argument_check_bits,
-                         type_argument_check_bits),
+                         token_pos),
         ic_data_(NULL),
         call_count_(0),
         function_(function),
@@ -3667,14 +3639,12 @@
                   PushArgumentsArray* arguments,
                   intptr_t deopt_id,
                   intptr_t call_count,
-                  ICData::RebindRule rebind_rule,
-                  intptr_t argument_check_bits = 0)
+                  ICData::RebindRule rebind_rule)
       : TemplateDartCall(deopt_id,
                          type_args_len,
                          argument_names,
                          arguments,
-                         token_pos,
-                         argument_check_bits),
+                         token_pos),
         ic_data_(NULL),
         call_count_(call_count),
         function_(function),
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index ec29c10e..dd4a560 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1766,7 +1766,7 @@
     case kYieldStatement: {
       builder_->ReadPosition();           // read position.
       word flags = builder_->ReadByte();  // read flags.
-      builder_->SkipExpression();         // read expression.
+      VisitExpression();                  // read expression.
 
       ASSERT(flags == kNativeYieldFlags);
       if (depth_.function_ == 0) {
@@ -5827,13 +5827,10 @@
     const Array& argument_names,
     ICData::RebindRule rebind_rule,
     const InferredTypeMetadata* result_type,
-    intptr_t type_args_count,
-    intptr_t argument_check_bits,
-    intptr_t type_argument_check_bits) {
+    intptr_t type_args_count) {
   return flow_graph_builder_->StaticCall(
       position, target, argument_count, argument_names, rebind_rule,
-      result_type, type_args_count, argument_check_bits,
-      type_argument_check_bits);
+      result_type, type_args_count);
 }
 
 Fragment StreamingFlowGraphBuilder::InstanceCall(
@@ -5857,13 +5854,10 @@
     const Array& argument_names,
     intptr_t checked_argument_count,
     const Function& interface_target,
-    const InferredTypeMetadata* result_type,
-    intptr_t argument_check_bits,
-    intptr_t type_argument_check_bits) {
+    const InferredTypeMetadata* result_type) {
   return flow_graph_builder_->InstanceCall(
       position, name, kind, type_args_len, argument_count, argument_names,
-      checked_argument_count, interface_target, result_type,
-      argument_check_bits, type_argument_check_bits);
+      checked_argument_count, interface_target, result_type);
 }
 
 Fragment StreamingFlowGraphBuilder::ThrowException(TokenPosition position) {
@@ -6291,7 +6285,7 @@
   const TokenPosition position = ReadPosition();  // read position.
   if (p != NULL) *p = position;
 
-  uint8_t flags = ReadFlags();  // read flags
+  ReadFlags();  // skip flags
 
   instructions += BuildExpression();  // read receiver.
 
@@ -6319,12 +6313,6 @@
     ASSERT(setter_name.raw() == interface_target->name());
   }
 
-  intptr_t argument_check_bits = 0;
-  if (I->strong()) {
-    argument_check_bits = ArgumentCheckBitsForSetter(
-        *interface_target, static_cast<DispatchCategory>(flags & 3));
-  }
-
   if (direct_call.check_receiver_for_null_) {
     instructions += CheckNull(position, receiver);
   }
@@ -6333,15 +6321,14 @@
     ASSERT(FLAG_precompiled_mode);
     instructions +=
         StaticCall(position, direct_call.target_, 2, Array::null_array(),
-                   ICData::kNoRebind, /* result_type = */ NULL,
-                   /*type_args_len=*/0, argument_check_bits);
+                   ICData::kNoRebind, /* result_type = */ NULL);
   } else {
     const intptr_t kTypeArgsLen = 0;
     const intptr_t kNumArgsChecked = 1;
     instructions +=
         InstanceCall(position, setter_name, Token::kSET, kTypeArgsLen, 2,
                      Array::null_array(), kNumArgsChecked, *interface_target,
-                     /* result_type = */ NULL, argument_check_bits);
+                     /* result_type = */ NULL);
   }
 
   instructions += Drop();  // Drop result of the setter invocation.
@@ -6624,7 +6611,7 @@
   const TokenPosition position = ReadPosition();  // read position.
   if (p != NULL) *p = position;
 
-  uint8_t flags = ReadFlags();  // read flags.
+  ReadFlags();  // skip flags.
 
   Fragment instructions(NullConstant());
   LocalVariable* value = MakeTemporary();
@@ -6643,9 +6630,6 @@
   instructions += StoreLocal(TokenPosition::kNoSource, value);
   instructions += PushArgument();
 
-  intptr_t argument_check_bits = ArgumentCheckBitsForSetter(
-      target, static_cast<DispatchCategory>(flags & 3));
-
   // Static calls are marked as "no-rebind", which is currently safe because
   // DirectPropertyGet are only used in enums (index in toString) and enums
   // can't change their structure during hot reload.
@@ -6653,9 +6637,7 @@
   // have to be adjusted.
   instructions +=
       StaticCall(position, target, 2, Array::null_array(), ICData::kNoRebind,
-                 /* result_type = */ NULL,
-                 /*type_args_len=*/0, argument_check_bits,
-                 /*type_argument_check_bits=*/0);
+                 /* result_type = */ NULL);
 
   return instructions + Drop();
 }
@@ -6752,177 +6734,6 @@
          tag == kSpecialIntLiteral || tag == kDoubleLiteral;
 }
 
-intptr_t StreamingFlowGraphBuilder::ArgumentCheckBitsForSetter(
-    const Function& interface_target,
-    DispatchCategory category) {
-  intptr_t argument_check_bits = 0;
-
-  switch (category) {
-    case DynamicDispatch:
-      argument_check_bits = 2;  // 1 for value, 0 for receiver
-      break;
-    case Closure:
-      // A property set cannot be a closure call.
-      UNREACHABLE();
-    case ViaThis:
-      // All bits are 0.
-      break;
-    case Interface: {
-      // TODO(sjindel): Revise checking interface target for null.
-      if (interface_target.IsNull() ||
-          !interface_target.IsImplicitGetterOrSetter()) {
-        intptr_t type_argument_check_bits_unused;
-        ArgumentCheckBitsForInvocation(
-            1, 0, 1, Array::null_array(), interface_target, category,
-            &argument_check_bits, &type_argument_check_bits_unused);
-        break;
-      }
-
-      const Field& target_field =
-          Field::Handle(interface_target.LookupImplicitGetterSetterField());
-      ASSERT(!target_field.IsNull());
-      TypedData& kernel_data = TypedData::Handle(Z, target_field.KernelData());
-      ASSERT(!kernel_data.IsNull());
-      AlternativeReadingScope r(reader_, &kernel_data,
-                                target_field.kernel_offset());
-      AlternativeScriptScope s(&translation_helper_,
-                               Script::Handle(target_field.Script()), script());
-
-      FieldHelper helper(this);
-      helper.ReadUntilIncluding(FieldHelper::kFlags);
-
-      argument_check_bits = 1;  // indicate dispatch category
-      if (helper.IsGenericCovariantInterface()) {
-        argument_check_bits |= 1 << 1;
-      }
-    }
-  }
-
-  return argument_check_bits;
-}
-
-void StreamingFlowGraphBuilder::ArgumentCheckBitsForInvocation(
-    intptr_t argument_count,  // excluding receiver
-    intptr_t type_argument_count,
-    intptr_t positional_argument_count,
-    const Array& argument_names,
-    const Function& interface_target,
-    DispatchCategory category,
-    intptr_t* argument_bits /*out*/,
-    intptr_t* type_argument_bits /*out*/) {
-  intptr_t argument_check_bits = 0;
-  intptr_t type_argument_check_bits = 0;
-
-  // If there are more than 'kBitsPerWord - 1' arguments, the rest will be
-  // assumed to be marked as 1 (the '-1' is because of the receiver).
-  int strong_checked_arguments =
-      Utils::Minimum<intptr_t>(argument_count, kBitsPerWord - 1);
-  int strong_checked_type_arguments =
-      Utils::Minimum<intptr_t>(type_argument_count, kBitsPerWord);
-
-  switch (category) {
-    case DynamicDispatch:
-      // All bits are 1 except the receiver which is 0.
-      argument_check_bits = Utils::SignedNBitMask(strong_checked_arguments)
-                            << 1;
-      type_argument_check_bits =
-          Utils::SignedNBitMask(strong_checked_type_arguments);
-    case ViaThis:
-      // All bits are 0.
-      break;
-    case Closure:
-      // All bits at 1.
-      argument_check_bits = Utils::SignedNBitMask(strong_checked_arguments + 1);
-      type_argument_check_bits =
-          Utils::SignedNBitMask(strong_checked_type_arguments);
-      break;
-    case Interface: {
-      ASSERT(!interface_target.IsNull() || !I->strong());
-      if (interface_target.IsNull()) {
-        argument_check_bits =
-            Utils::SignedNBitMask(strong_checked_arguments + 1);
-        type_argument_check_bits =
-            Utils::SignedNBitMask(strong_checked_type_arguments);
-        break;
-      }
-      argument_check_bits = 1;
-      TypedData& kernel_data =
-          TypedData::Handle(Z, interface_target.KernelData());
-      ASSERT(!kernel_data.IsNull());
-      AlternativeReadingScope _r(reader_, &kernel_data,
-                                 interface_target.kernel_offset());
-      AlternativeScriptScope _s(&translation_helper_,
-                                Script::Handle(interface_target.script()),
-                                script());
-      ReadUntilFunctionNode();
-
-      FunctionNodeHelper fn_helper(this);
-      fn_helper.ReadUntilExcluding(FunctionNodeHelper::kTypeParameters);
-      intptr_t num_interface_type_params = ReadListLength();
-      // Maybe this can be ==?
-      ASSERT(num_interface_type_params >= type_argument_count);
-
-      for (intptr_t i = 0; i < num_interface_type_params; ++i) {
-        uint8_t flags = ReadFlags();
-        SkipListOfExpressions();
-        SkipStringReference();
-        SkipDartType();
-        if (i >= strong_checked_type_arguments) continue;
-        if (flags & TypeParameterHelper::kIsGenericCovariantInterface) {
-          type_argument_check_bits |= Utils::Bit(i);
-        }
-      }
-
-      fn_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
-      fn_helper.ReadUntilExcluding(FunctionNodeHelper::kPositionalParameters);
-      intptr_t num_interface_pos_params = ReadListLength();
-      ASSERT(num_interface_pos_params >= positional_argument_count);
-
-      intptr_t arg = 0;
-      for (; arg < num_interface_pos_params; ++arg) {
-        VariableDeclarationHelper var_helper(this);
-        var_helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd);
-        if (arg >= strong_checked_arguments) continue;
-        if (var_helper.IsGenericCovariantInterface()) {
-          argument_check_bits |= Utils::Bit(arg + 1);  // +1 for the receiver
-        }
-      }
-
-      fn_helper.SetJustRead(FunctionNodeHelper::kPositionalParameters);
-      if (argument_names.IsNull()) break;
-
-      fn_helper.ReadUntilExcluding(FunctionNodeHelper::kNamedParameters);
-      intptr_t num_interface_named_params = ReadListLength();
-      for (intptr_t i = 0;
-           i < argument_names.Length() && arg <= strong_checked_arguments;
-           ++i, ++arg) {
-        const String& arg_name =
-            String::Handle(Z, String::RawCast(argument_names.At(i)));
-
-        // Scan through the named parameters of the interface target to find
-        // the right one.
-        AlternativeReadingScope _(reader_);
-        for (intptr_t j = 0; j < num_interface_named_params; ++j) {
-          VariableDeclarationHelper var_helper(this);
-          var_helper.ReadUntilExcluding(VariableDeclarationHelper::kEnd);
-          const String& param_name = H.DartSymbol(var_helper.name_index_);
-          if (!param_name.Equals(arg_name)) continue;
-          if (var_helper.IsGenericCovariantInterface()) {
-            argument_check_bits |= Utils::NBitMask(arg + 1);
-          }
-          break;
-        }
-      }
-      break;
-    }
-    default:
-      UNREACHABLE();
-  }
-
-  *argument_bits = argument_check_bits;
-  *type_argument_bits = type_argument_check_bits;
-}
-
 Fragment StreamingFlowGraphBuilder::BuildMethodInvocation(TokenPosition* p) {
   const intptr_t offset = ReaderOffset() - 1;     // Include the tag.
   const TokenPosition position = ReadPosition();  // read position.
@@ -6933,7 +6744,7 @@
   const InferredTypeMetadata result_type =
       inferred_type_metadata_helper_.GetInferredType(offset);
 
-  uint8_t flags = ReadFlags();  // read flags.
+  ReadFlags();  // skip flags.
 
   const Tag receiver_tag = PeekTag();  // peek tag for receiver.
   if (IsNumberLiteral(receiver_tag) &&
@@ -7068,27 +6879,15 @@
     instructions += CheckNull(position, receiver_temp);
   }
 
-  intptr_t argument_check_bits = 0;
-  intptr_t type_argument_check_bits = 0;
-  if (I->strong()) {
-    ArgumentCheckBitsForInvocation(
-        argument_count - 1, type_args_len, positional_argument_count,
-        argument_names, *interface_target,
-        static_cast<DispatchCategory>(flags & 3), &argument_check_bits,
-        &type_argument_check_bits);
-  }
-
   if (!direct_call.target_.IsNull()) {
     ASSERT(FLAG_precompiled_mode);
     instructions += StaticCall(position, direct_call.target_, argument_count,
                                argument_names, ICData::kNoRebind, &result_type,
-                               type_args_len, argument_check_bits,
-                               type_argument_check_bits);
+                               type_args_len);
   } else {
     instructions += InstanceCall(
         position, name, token_kind, type_args_len, argument_count,
-        argument_names, checked_argument_count, *interface_target, &result_type,
-        argument_check_bits, type_argument_check_bits);
+        argument_names, checked_argument_count, *interface_target, &result_type);
   }
 
   // Drop temporaries preserving result on the top of the stack.
@@ -7120,7 +6919,7 @@
   const InferredTypeMetadata result_type =
       inferred_type_metadata_helper_.GetInferredType(offset);
 
-  uint8_t flags = ReadFlags();  // read flags.
+  ReadFlags();  // skip flags.
 
   Tag receiver_tag = PeekTag();  // peek tag for receiver.
 
@@ -7177,16 +6976,9 @@
                      &positional_argument_count);  // read arguments.
   ++argument_count;
 
-  intptr_t argument_check_bits, type_argument_check_bits;
-  ArgumentCheckBitsForInvocation(
-      argument_count, type_args_len, positional_argument_count, argument_names,
-      target, static_cast<DispatchCategory>(flags & 3), &argument_check_bits,
-      &type_argument_check_bits);
-
   return instructions +
          StaticCall(position, target, argument_count, argument_names,
-                    ICData::kNoRebind, &result_type, type_args_len,
-                    argument_check_bits, type_argument_check_bits);
+                    ICData::kNoRebind, &result_type, type_args_len);
 }
 
 Fragment StreamingFlowGraphBuilder::BuildSuperMethodInvocation(
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index b99111b..34df86f 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -1148,9 +1148,7 @@
                       const Array& argument_names,
                       ICData::RebindRule rebind_rule,
                       const InferredTypeMetadata* result_type = NULL,
-                      intptr_t type_args_len = 0,
-                      intptr_t argument_check_bits = 0,
-                      intptr_t type_argument_check_bits = 0);
+                      intptr_t type_args_len = 0);
   Fragment InstanceCall(TokenPosition position,
                         const String& name,
                         Token::Kind kind,
@@ -1164,9 +1162,7 @@
                         const Array& argument_names,
                         intptr_t checked_argument_count,
                         const Function& interface_target,
-                        const InferredTypeMetadata* result_type = NULL,
-                        intptr_t argument_check_bits = 0,
-                        intptr_t type_argument_check_bits = 0);
+                        const InferredTypeMetadata* result_type = NULL);
 
   enum TypeChecksToBuild {
     kDefaultTypeChecks,
@@ -1332,19 +1328,6 @@
                                bool is_closure,
                                FunctionNodeHelper* function_node_helper);
 
-  intptr_t ArgumentCheckBitsForSetter(const Function& interface_target,
-                                      DispatchCategory category);
-
-  void ArgumentCheckBitsForInvocation(
-      intptr_t argument_count,  // excluding receiver
-      intptr_t type_argument_count,
-      intptr_t positional_argument_count,
-      const Array& argument_names,
-      const Function& interface_target,
-      DispatchCategory category,
-      intptr_t* argument_bits,
-      intptr_t* type_argument_bits);
-
   const Script& script() { return script_; }
 
   // Scan through metadata mappings section and cache offsets for recognized
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index f004628..ede8726 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1235,15 +1235,13 @@
                                         const Array& argument_names,
                                         intptr_t checked_argument_count,
                                         const Function& interface_target,
-                                        const InferredTypeMetadata* result_type,
-                                        intptr_t argument_bits,
-                                        intptr_t type_argument_bits) {
+                                        const InferredTypeMetadata* result_type) {
   const intptr_t total_count = argument_count + (type_args_len > 0 ? 1 : 0);
   ArgumentArray arguments = GetArguments(total_count);
   InstanceCallInstr* call = new (Z) InstanceCallInstr(
       position, name, kind, arguments, type_args_len, argument_names,
       checked_argument_count, ic_data_array_, GetNextDeoptId(),
-      interface_target, argument_bits, type_argument_bits);
+      interface_target);
   if (result_type != NULL) {
     call->SetResultType(Z, CompileType::CreateNullable(result_type->nullable,
                                                        result_type->cid));
@@ -1512,15 +1510,12 @@
                                       const Array& argument_names,
                                       ICData::RebindRule rebind_rule,
                                       const InferredTypeMetadata* result_type,
-                                      intptr_t type_args_count,
-                                      intptr_t argument_bits,
-                                      intptr_t type_argument_check_bits) {
+                                      intptr_t type_args_count) {
   const intptr_t total_count = argument_count + (type_args_count > 0 ? 1 : 0);
   ArgumentArray arguments = GetArguments(total_count);
   StaticCallInstr* call = new (Z)
       StaticCallInstr(position, target, type_args_count, argument_names,
-                      arguments, ic_data_array_, GetNextDeoptId(), rebind_rule,
-                      argument_bits, type_argument_check_bits);
+                      arguments, ic_data_array_, GetNextDeoptId(), rebind_rule);
   const intptr_t list_cid =
       GetResultCidOfListFactory(Z, target, argument_count);
   if (list_cid != kDynamicCid) {
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 6d9948d..13df421 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -700,9 +700,7 @@
                         const Array& argument_names,
                         intptr_t checked_argument_count,
                         const Function& interface_target,
-                        const InferredTypeMetadata* result_type = NULL,
-                        intptr_t argument_bits = 0,
-                        intptr_t type_argument_bits = 0);
+                        const InferredTypeMetadata* result_type = NULL);
   Fragment ClosureCall(intptr_t type_args_len,
                        intptr_t argument_count,
                        const Array& argument_names);
@@ -731,9 +729,7 @@
                       const Array& argument_names,
                       ICData::RebindRule rebind_rule,
                       const InferredTypeMetadata* result_type = NULL,
-                      intptr_t type_args_len = 0,
-                      intptr_t argument_bits = 0,
-                      intptr_t type_argument_check_bits = 0);
+                      intptr_t type_args_len = 0);
   Fragment StoreIndexed(intptr_t class_id);
   Fragment StoreInstanceFieldGuarded(const Field& field,
                                      bool is_initialization_store);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 21580bd..840ca2f 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -22574,15 +22574,45 @@
       }
     }
   }
+
+  // Workaround for http://dartbug.com/32087: currently Kernel front-end
+  // embeds absolute build-time paths to core library sources into Kernel
+  // binaries this introduces discrepancy between how stack traces were
+  // looked like in legacy pipeline and how they look in Dart 2 pipeline and
+  // breaks users' code that attempts to pattern match and filter various
+  // irrelevant frames (e.g. frames from dart:async).
+  // To work around this issue we reformat urls of scripts belonging to
+  // dart:-scheme libraries to look like they looked like in legacy pipeline:
+  //
+  //               dart:libname/filename.dart
+  //
+  const char* url_string = url.ToCString();
+  if (script.kernel_program_info() != KernelProgramInfo::null()) {
+    const Class& owner = Class::Handle(function.Owner());
+    const Library& lib = Library::Handle(owner.library());
+    if (lib.is_dart_scheme()) {
+      // Search backwards until '/' is found. That gives us the filename.
+      intptr_t pos = strlen(url_string) - 1;
+      while (pos >= 0 && url_string[pos] != '/') {
+        pos--;
+      }
+      const char* filename = url_string + (pos + 1);
+
+      // Glue together canonic library url (e.g. dart:async) and filename.
+      url_string = zone->PrintToString(
+          "%s/%s", String::Handle(lib.url()).ToCString(), filename);
+    }
+  }
+
   if (column >= 0) {
     buffer->Printf("#%-6" Pd " %s (%s:%" Pd ":%" Pd ")\n", frame_index,
-                   function_name.ToCString(), url.ToCString(), line, column);
+                   function_name.ToCString(), url_string, line, column);
   } else if (line >= 0) {
     buffer->Printf("#%-6" Pd " %s (%s:%" Pd ")\n", frame_index,
-                   function_name.ToCString(), url.ToCString(), line);
+                   function_name.ToCString(), url_string, line);
   } else {
     buffer->Printf("#%-6" Pd " %s (%s)\n", frame_index,
-                   function_name.ToCString(), url.ToCString());
+                   function_name.ToCString(), url_string);
   }
 }
 
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index c15a3f0..9c20289 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -10,6 +10,10 @@
 ///     import 'dart:typed_data';
 library dart.typed_data;
 
+import "dart:_internal" show UnmodifiableListBase;
+
+part "unmodifiable_typed_data.dart";
+
 /**
  * A sequence of bytes underlying a typed data object.
  *
diff --git a/sdk/lib/typed_data/typed_data_sources.gni b/sdk/lib/typed_data/typed_data_sources.gni
index daa50aa..23ba0f0 100644
--- a/sdk/lib/typed_data/typed_data_sources.gni
+++ b/sdk/lib/typed_data/typed_data_sources.gni
@@ -5,4 +5,5 @@
 typed_data_sdk_sources = [
   "typed_data.dart",
   # The above file needs to be first if additional parts are added to the lib.
+  "unmodifiable_typed_data.dart",
 ]
diff --git a/sdk/lib/typed_data/unmodifiable_typed_data.dart b/sdk/lib/typed_data/unmodifiable_typed_data.dart
new file mode 100644
index 0000000..4cc5af7
--- /dev/null
+++ b/sdk/lib/typed_data/unmodifiable_typed_data.dart
@@ -0,0 +1,303 @@
+// 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.
+
+part of dart.typed_data;
+
+/**
+ * A read-only view of a [ByteBuffer].
+ */
+class UnmodifiableByteBufferView implements ByteBuffer {
+  final ByteBuffer _data;
+
+  UnmodifiableByteBufferView(ByteBuffer data) : _data = data;
+
+  int get lengthInBytes => _data.lengthInBytes;
+
+  Uint8List asUint8List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableUint8ListView(_data.asUint8List(offsetInBytes, length));
+
+  Int8List asInt8List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableInt8ListView(_data.asInt8List(offsetInBytes, length));
+
+  Uint8ClampedList asUint8ClampedList([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableUint8ClampedListView(
+          _data.asUint8ClampedList(offsetInBytes, length));
+
+  Uint16List asUint16List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableUint16ListView(_data.asUint16List(offsetInBytes, length));
+
+  Int16List asInt16List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableInt16ListView(_data.asInt16List(offsetInBytes, length));
+
+  Uint32List asUint32List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableUint32ListView(_data.asUint32List(offsetInBytes, length));
+
+  Int32List asInt32List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableInt32ListView(_data.asInt32List(offsetInBytes, length));
+
+  Uint64List asUint64List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableUint64ListView(_data.asUint64List(offsetInBytes, length));
+
+  Int64List asInt64List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableInt64ListView(_data.asInt64List(offsetInBytes, length));
+
+  Int32x4List asInt32x4List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableInt32x4ListView(
+          _data.asInt32x4List(offsetInBytes, length));
+
+  Float32List asFloat32List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableFloat32ListView(
+          _data.asFloat32List(offsetInBytes, length));
+
+  Float64List asFloat64List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableFloat64ListView(
+          _data.asFloat64List(offsetInBytes, length));
+
+  Float32x4List asFloat32x4List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableFloat32x4ListView(
+          _data.asFloat32x4List(offsetInBytes, length));
+
+  Float64x2List asFloat64x2List([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableFloat64x2ListView(
+          _data.asFloat64x2List(offsetInBytes, length));
+
+  ByteData asByteData([int offsetInBytes = 0, int length]) =>
+      new UnmodifiableByteDataView(_data.asByteData(offsetInBytes, length));
+}
+
+/**
+ * A read-only view of a [ByteData].
+ */
+class UnmodifiableByteDataView implements ByteData {
+  final ByteData _data;
+
+  UnmodifiableByteDataView(ByteData data) : _data = data;
+
+  int getInt8(int byteOffset) => _data.getInt8(byteOffset);
+
+  void setInt8(int byteOffset, int value) => _unsupported();
+
+  int getUint8(int byteOffset) => _data.getUint8(byteOffset);
+
+  void setUint8(int byteOffset, int value) => _unsupported();
+
+  int getInt16(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getInt16(byteOffset, endian);
+
+  void setInt16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int getUint16(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getUint16(byteOffset, endian);
+
+  void setUint16(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int getInt32(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getInt32(byteOffset, endian);
+
+  void setInt32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int getUint32(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getUint32(byteOffset, endian);
+
+  void setUint32(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int getInt64(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getInt64(byteOffset, endian);
+
+  void setInt64(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int getUint64(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getUint64(byteOffset, endian);
+
+  void setUint64(int byteOffset, int value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  double getFloat32(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getFloat32(byteOffset, endian);
+
+  void setFloat32(int byteOffset, double value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  double getFloat64(int byteOffset, [Endian endian = Endian.big]) =>
+      _data.getFloat64(byteOffset, endian);
+
+  void setFloat64(int byteOffset, double value, [Endian endian = Endian.big]) =>
+      _unsupported();
+
+  int get elementSizeInBytes => _data.elementSizeInBytes;
+
+  int get offsetInBytes => _data.offsetInBytes;
+
+  int get lengthInBytes => _data.lengthInBytes;
+
+  ByteBuffer get buffer => new UnmodifiableByteBufferView(_data.buffer);
+
+  void _unsupported() {
+    throw new UnsupportedError(
+        "An UnmodifiableByteDataView may not be modified");
+  }
+}
+
+abstract class _UnmodifiableListMixin<N, L extends List<N>,
+    TD extends TypedData> {
+  L get _list;
+  TD get _data => (_list as TD);
+
+  int get length => _list.length;
+
+  N operator [](int index) => _list[index];
+
+  int get elementSizeInBytes => _data.elementSizeInBytes;
+
+  int get offsetInBytes => _data.offsetInBytes;
+
+  int get lengthInBytes => _data.lengthInBytes;
+
+  ByteBuffer get buffer => new UnmodifiableByteBufferView(_data.buffer);
+}
+
+/**
+ * View of a [Uint8List] that disallows modification.
+ */
+class UnmodifiableUint8ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Uint8List, Uint8List>
+    implements Uint8List {
+  final Uint8List _list;
+  UnmodifiableUint8ListView(Uint8List list) : _list = list;
+}
+
+/**
+ * View of a [Int8List] that disallows modification.
+ */
+class UnmodifiableInt8ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Int8List, Int8List>
+    implements Int8List {
+  final Int8List _list;
+  UnmodifiableInt8ListView(Int8List list) : _list = list;
+}
+
+/**
+ * View of a [Uint8ClampedList] that disallows modification.
+ */
+class UnmodifiableUint8ClampedListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Uint8ClampedList, Uint8ClampedList>
+    implements Uint8ClampedList {
+  final Uint8ClampedList _list;
+  UnmodifiableUint8ClampedListView(Uint8ClampedList list) : _list = list;
+}
+
+/**
+ * View of a [Uint16List] that disallows modification.
+ */
+class UnmodifiableUint16ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Uint16List, Uint16List>
+    implements Uint16List {
+  final Uint16List _list;
+  UnmodifiableUint16ListView(Uint16List list) : _list = list;
+}
+
+/**
+ * View of a [Int16List] that disallows modification.
+ */
+class UnmodifiableInt16ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Int16List, Int16List>
+    implements Int16List {
+  final Int16List _list;
+  UnmodifiableInt16ListView(Int16List list) : _list = list;
+}
+
+/**
+ * View of a [Uint32List] that disallows modification.
+ */
+class UnmodifiableUint32ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Uint32List, Uint32List>
+    implements Uint32List {
+  final Uint32List _list;
+  UnmodifiableUint32ListView(Uint32List list) : _list = list;
+}
+
+/**
+ * View of a [Int32List] that disallows modification.
+ */
+class UnmodifiableInt32ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Int32List, Int32List>
+    implements Int32List {
+  final Int32List _list;
+  UnmodifiableInt32ListView(Int32List list) : _list = list;
+}
+
+/**
+ * View of a [Uint64List] that disallows modification.
+ */
+class UnmodifiableUint64ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Uint64List, Uint64List>
+    implements Uint64List {
+  final Uint64List _list;
+  UnmodifiableUint64ListView(Uint64List list) : _list = list;
+}
+
+/**
+ * View of a [Int64List] that disallows modification.
+ */
+class UnmodifiableInt64ListView extends UnmodifiableListBase<int>
+    with _UnmodifiableListMixin<int, Int64List, Int64List>
+    implements Int64List {
+  final Int64List _list;
+  UnmodifiableInt64ListView(Int64List list) : _list = list;
+}
+
+/**
+ * View of a [Int32x4List] that disallows modification.
+ */
+class UnmodifiableInt32x4ListView extends UnmodifiableListBase<Int32x4>
+    with _UnmodifiableListMixin<Int32x4, Int32x4List, Int32x4List>
+    implements Int32x4List {
+  final Int32x4List _list;
+  UnmodifiableInt32x4ListView(Int32x4List list) : _list = list;
+}
+
+/**
+ * View of a [Float32x4List] that disallows modification.
+ */
+class UnmodifiableFloat32x4ListView extends UnmodifiableListBase<Float32x4>
+    with _UnmodifiableListMixin<Float32x4, Float32x4List, Float32x4List>
+    implements Float32x4List {
+  final Float32x4List _list;
+  UnmodifiableFloat32x4ListView(Float32x4List list) : _list = list;
+}
+
+/**
+ * View of a [Float64x2List] that disallows modification.
+ */
+class UnmodifiableFloat64x2ListView extends UnmodifiableListBase<Float64x2>
+    with _UnmodifiableListMixin<Float64x2, Float64x2List, Float64x2List>
+    implements Float64x2List {
+  final Float64x2List _list;
+  UnmodifiableFloat64x2ListView(Float64x2List list) : _list = list;
+}
+
+/**
+ * View of a [Float32List] that disallows modification.
+ */
+class UnmodifiableFloat32ListView extends UnmodifiableListBase<double>
+    with _UnmodifiableListMixin<double, Float32List, Float32List>
+    implements Float32List {
+  final Float32List _list;
+  UnmodifiableFloat32ListView(Float32List list) : _list = list;
+}
+
+/**
+ * View of a [Float64List] that disallows modification.
+ */
+class UnmodifiableFloat64ListView extends UnmodifiableListBase<double>
+    with _UnmodifiableListMixin<double, Float64List, Float64List>
+    implements Float64List {
+  final Float64List _list;
+  UnmodifiableFloat64ListView(Float64List list) : _list = list;
+}
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 0e0083a..c7649a6 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -37,7 +37,8 @@
 old_frontend/resolver_test: RuntimeError # Test must be updated given new parser recovery
 packages/*: Skip # Skip packages folder
 quarantined/http_test: Pass, Slow
-rti/rti_need_test: Pass, Slow, Fail # Issue 32055
+rti/rti_emission_test: Pass, Slow
+rti/rti_need_test: Pass, Slow
 serialization/analysis1_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
 serialization/analysis3_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
 serialization/analysis4_test: Skip # Skip most serialization tests. These are very slow and are no longer a priority.
diff --git a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
index b51545e..23dfb6f 100644
--- a/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
+++ b/tests/compiler/dart2js/equivalence/id_equivalence_helper.dart
@@ -855,10 +855,17 @@
 
 /// Set of features used in annotations.
 class Features {
-  Map<String, String> _features = <String, String>{};
+  Map<String, Object> _features = <String, Object>{};
 
   void add(String key, {var value: ''}) {
-    _features[key] = value;
+    _features[key] = value.toString();
+  }
+
+  void addElement(String key, [var value]) {
+    List<String> list = _features.putIfAbsent(key, () => <String>[]);
+    if (value != null) {
+      list.add(value.toString());
+    }
   }
 
   bool containsKey(String key) {
@@ -879,12 +886,15 @@
     StringBuffer sb = new StringBuffer();
     bool needsComma = false;
     for (String name in _features.keys.toList()..sort()) {
-      String value = _features[name];
+      dynamic value = _features[name];
       if (value != null) {
         if (needsComma) {
           sb.write(',');
         }
         sb.write(name);
+        if (value is List<String>) {
+          value = '[${(value..sort()).join(',')}]';
+        }
         if (value != '') {
           sb.write('=');
           sb.write(value);
diff --git a/tests/compiler/dart2js/helpers/program_lookup.dart b/tests/compiler/dart2js/helpers/program_lookup.dart
index c3ef07a..5b1b8b1 100644
--- a/tests/compiler/dart2js/helpers/program_lookup.dart
+++ b/tests/compiler/dart2js/helpers/program_lookup.dart
@@ -36,7 +36,7 @@
   }
 
   Class getClass(ClassEntity element) {
-    return getClassData(element).cls;
+    return getClassData(element)?.cls;
   }
 
   Method getMethod(FunctionEntity function) {
diff --git a/tests/compiler/dart2js/old_frontend/analyze_test_test.dart b/tests/compiler/dart2js/old_frontend/analyze_test_test.dart
index 3cf3f42..495ce73 100644
--- a/tests/compiler/dart2js/old_frontend/analyze_test_test.dart
+++ b/tests/compiler/dart2js/old_frontend/analyze_test_test.dart
@@ -28,6 +28,7 @@
 const List<String> SKIP_LIST = const <String>[
   // Helper files:
   "/data/",
+  "/emission/",
   "/side_effects/",
   "quarantined/http_launch_data/",
   "mirrors_helper.dart",
diff --git a/tests/compiler/dart2js/old_frontend/analyze_unused_dart2js_test.dart b/tests/compiler/dart2js/old_frontend/analyze_unused_dart2js_test.dart
index f0e1c8d..2de14d2 100644
--- a/tests/compiler/dart2js/old_frontend/analyze_unused_dart2js_test.dart
+++ b/tests/compiler/dart2js/old_frontend/analyze_unused_dart2js_test.dart
@@ -58,6 +58,10 @@
   "pkg/kernel/lib/transformations/closure/": const [
     "Duplicated library name 'kernel.transformations.closure.converter'",
   ],
+
+  "pkg/compiler/lib/src/js_backend/runtime_types.dart": const [
+    "'void' is not a subtype of bound 'Object' for type variable",
+  ],
 };
 
 void main() {
diff --git a/tests/compiler/dart2js/old_frontend/size_test.dart b/tests/compiler/dart2js/old_frontend/size_test.dart
index af9817a..95a1946 100644
--- a/tests/compiler/dart2js/old_frontend/size_test.dart
+++ b/tests/compiler/dart2js/old_frontend/size_test.dart
@@ -30,7 +30,7 @@
       compileAll(TEST, coreSource: DEFAULT_CORELIB_WITH_LIST).then((generated) {
         return MockCompiler.create((MockCompiler compiler) {
           // Make sure no class is emitted.
-          Expect.isFalse(generated.contains('finishClasses'));
+          Expect.isFalse(generated.contains('finishClasses'), generated);
         });
       }));
 }
diff --git a/tests/compiler/dart2js/rti/backend_type_helper_test.dart b/tests/compiler/dart2js/rti/backend_type_helper_test.dart
new file mode 100644
index 0000000..6d47050
--- /dev/null
+++ b/tests/compiler/dart2js/rti/backend_type_helper_test.dart
@@ -0,0 +1,43 @@
+// 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.
+
+import 'dart:io';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/js_emitter/program_builder/program_builder.dart';
+import 'package:compiler/src/world.dart';
+import 'package:expect/expect.dart';
+import '../helpers/program_lookup.dart';
+import '../memory_compiler.dart';
+
+main() {
+  runTest({bool useKernel}) async {
+    CompilationResult result = await runCompiler(
+        entryPoint: Platform.script.resolve('data/subtype_named_args.dart'),
+        options: useKernel ? [Flags.useKernel] : []);
+    Expect.isTrue(result.isSuccess);
+    Compiler compiler = result.compiler;
+    ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
+    ProgramLookup programLookup = new ProgramLookup(compiler);
+
+    List<ClassEntity> found = <ClassEntity>[];
+    for (ClassEntity element
+        in Collector.getBackendTypeHelpers(closedWorld.commonElements)) {
+      if (programLookup.getClass(element) != null) {
+        found.add(element);
+      }
+    }
+    Expect.isTrue(found.isEmpty, "Classes ${found} should not be emitted");
+  }
+
+  asyncTest(() async {
+    print('--test from ast---------------------------------------------------');
+    await runTest(useKernel: false);
+    print('--test from kernel------------------------------------------------');
+    await runTest(useKernel: true);
+  });
+}
diff --git a/tests/compiler/dart2js/rti/data/function_subtype_local5.dart b/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
new file mode 100644
index 0000000..5acd91f
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/function_subtype_local5.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2013, 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.
+// Dart test program for constructors and initializers.
+
+// Check function subtyping for local functions on generic type against generic
+// typedefs.
+
+import 'package:expect/expect.dart';
+
+typedef int Foo<T>(T a, [String b]);
+typedef int Bar<T>(T a, [String b]);
+typedef int Baz<T>(T a, {String b});
+typedef int Boz<T>(T a);
+typedef int Biz<T>(T a, int b);
+
+/*class: C:explicit=[int Function(C.T),int Function(C.T,[String]),int Function(C.T,int),int Function(C.T,{,b:String})],needsArgs*/
+class C<T> {
+  void test(String nameOfT, bool expectedResult) {
+    int foo(bool a, [String b]) => null;
+    int baz(bool a, {String b}) => null;
+
+    Expect.equals(expectedResult, foo is Foo<T>, 'foo is Foo<$nameOfT>');
+    Expect.equals(expectedResult, foo is Bar<T>, 'foo is Bar<$nameOfT>');
+    Expect.isFalse(foo is Baz<T>, 'foo is Baz<$nameOfT>');
+    Expect.equals(expectedResult, foo is Boz<T>, 'foo is Boz<$nameOfT>');
+    Expect.isFalse(foo is Biz<T>, 'foo is Biz<$nameOfT>');
+
+    Expect.isFalse(baz is Foo<T>, 'baz is Foo<$nameOfT>');
+    Expect.isFalse(baz is Bar<T>, 'baz is Bar<$nameOfT>');
+    Expect.equals(expectedResult, baz is Baz<T>, 'baz is Baz<$nameOfT>');
+    Expect.equals(expectedResult, baz is Boz<T>, 'baz is Boz<$nameOfT>');
+    Expect.isFalse(baz is Biz<T>, 'bar is Biz<$nameOfT>');
+  }
+}
+
+/*class: D:needsArgs*/
+class D<S, T> extends C<T> {}
+
+main() {
+  new D<String, bool>().test('bool', true);
+  new D<bool, int>().test('int', false);
+  new D().test('dynamic', true);
+}
diff --git a/tests/compiler/dart2js/rti/data/generic_class_instantiate.dart b/tests/compiler/dart2js/rti/data/generic_class_instantiate.dart
index 8bf986a..65a7e4d 100644
--- a/tests/compiler/dart2js/rti/data/generic_class_instantiate.dart
+++ b/tests/compiler/dart2js/rti/data/generic_class_instantiate.dart
@@ -2,7 +2,7 @@
 // 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.
 
-/*class: A:arg,explicit=[B<A>]*/
+/*class: A:explicit=[B<A>]*/
 class A {}
 
 /*class: B:deps=[C],explicit=[B<A>],needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_class_is.dart b/tests/compiler/dart2js/rti/data/generic_class_is.dart
index d82f758..acfcaac 100644
--- a/tests/compiler/dart2js/rti/data/generic_class_is.dart
+++ b/tests/compiler/dart2js/rti/data/generic_class_is.dart
@@ -4,7 +4,7 @@
 
 import 'package:meta/dart2js.dart';
 
-/*class: A:arg,checked,implicit=[A]*/
+/*class: A:implicit=[A]*/
 class A {}
 
 /*class: B:direct,explicit=[B.T],needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_class_is2.dart b/tests/compiler/dart2js/rti/data/generic_class_is2.dart
index 612fe1d..508466d 100644
--- a/tests/compiler/dart2js/rti/data/generic_class_is2.dart
+++ b/tests/compiler/dart2js/rti/data/generic_class_is2.dart
@@ -5,12 +5,9 @@
 import 'package:expect/expect.dart';
 import 'package:meta/dart2js.dart';
 
-// TODO(johnniwinther): A, C and C2 should be checked or A1, C1, and C2 should
-// have checks againts A, C and C, respectively.
-/*class: A:arg,checks=[A],implicit=[List<A<C2>>,List<A<C>>]*/
+/*class: A:implicit=[List<A<C2>>,List<A<C>>]*/
 class A<T> {}
 
-/*class: A1:arg,checks=[A]*/
 class A1 implements A<C1> {}
 
 /*class: B:direct,explicit=[B.T],needsArgs*/
@@ -19,13 +16,12 @@
   method(var t) => t is T;
 }
 
-/*class: C:arg,checks=[C],implicit=[List<A<C>>]*/
+/*class: C:implicit=[List<A<C>>]*/
 class C {}
 
-/*class: C1:arg*/
 class C1 implements C {}
 
-/*class: C2:arg,checks=[C,C2],implicit=[List<A<C2>>]*/
+/*class: C2:implicit=[List<A<C2>>]*/
 class C2 implements C {}
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_closure_instantiate.dart b/tests/compiler/dart2js/rti/data/generic_closure_instantiate.dart
index cc83ed0..635ac78 100644
--- a/tests/compiler/dart2js/rti/data/generic_closure_instantiate.dart
+++ b/tests/compiler/dart2js/rti/data/generic_closure_instantiate.dart
@@ -5,8 +5,7 @@
 /*class: A:explicit=[B<A>]*/
 class A {}
 
-/*ast.class: B:deps=[closure],explicit=[B<A>],needsArgs*/
-/*kernel.class: B:arg,checks=[B],deps=[closure],explicit=[B<A>],needsArgs*/
+/*class: B:deps=[closure],explicit=[B<A>],needsArgs*/
 class B<T> {}
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/generic_creation.dart b/tests/compiler/dart2js/rti/data/generic_creation.dart
new file mode 100644
index 0000000..56adaeb
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/generic_creation.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2012, 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:expect/expect.dart";
+
+/*class: A:needsArgs*/
+/*element: A.:needsSignature*/
+class A<X, Y, Z> {
+  /*element: A.shift:needsSignature*/
+  shift() => new A<Z, X, Y>();
+  /*element: A.swap:needsSignature*/
+  swap() => new A<Z, Y, X>();
+  /*element: A.first:needsSignature*/
+  first() => new A<X, X, X>();
+  /*element: A.last:needsSignature*/
+  last() => new A<Z, Z, Z>();
+  /*element: A.wrap:needsSignature*/
+  wrap() => new A<A<X, X, X>, A<Y, Y, Y>, A<Z, Z, Z>>();
+}
+
+/*element: B.:needsSignature*/
+class B extends A<U, V, W> {}
+
+/*class: C:needsArgs*/
+/*element: C.:needsSignature*/
+class C<T> extends A<U, T, W> {}
+
+/*class: D:needsArgs*/
+/*element: D.:needsSignature*/
+class D<X, Y, Z> extends A<Y, Z, X> {}
+
+class U {}
+
+class V {}
+
+class W {}
+
+/*element: sameType:needsSignature*/
+sameType(a, b) => Expect.equals(a.runtimeType, b.runtimeType);
+
+/*element: main:needsSignature*/
+main() {
+  A a = new A<U, V, W>();
+  sameType(new A<W, U, V>(), a.shift());
+  sameType(new A<W, V, U>(), a.swap());
+  sameType(new A<U, U, U>(), a.first());
+  sameType(new A<W, W, W>(), a.last());
+  sameType(new A<A<U, U, U>, A<V, V, V>, A<W, W, W>>(), a.wrap());
+  B b = new B();
+  sameType(new A<A<U, U, U>, A<V, V, V>, A<W, W, W>>(), b.wrap());
+  C c = new C<V>();
+  sameType(new A<A<U, U, U>, A<V, V, V>, A<W, W, W>>(), c.wrap());
+  D d = new D<U, V, W>();
+  sameType(new A<A<V, V, V>, A<W, W, W>, A<U, U, U>>(), d.wrap());
+}
diff --git a/tests/compiler/dart2js/rti/data/generic_instanceof4.dart b/tests/compiler/dart2js/rti/data/generic_instanceof4.dart
index b035806..16b3327 100644
--- a/tests/compiler/dart2js/rti/data/generic_instanceof4.dart
+++ b/tests/compiler/dart2js/rti/data/generic_instanceof4.dart
@@ -12,7 +12,7 @@
   }
 }
 
-/*class: BB:arg,checked,implicit=[BB]*/
+/*class: BB:implicit=[BB]*/
 class BB {}
 
 /*class: B:implicit=[B.T],indirect,needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_method1_strong.dart b/tests/compiler/dart2js/rti/data/generic_method1_strong.dart
index 376861d..651976b 100644
--- a/tests/compiler/dart2js/rti/data/generic_method1_strong.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method1_strong.dart
@@ -13,9 +13,7 @@
   }
 }
 
-// TODO(johnniwinther): Should include 'arg'. Update the 'checkedArguments'
-// computation to take method type arguments into account.
-/*class: BB:checked,implicit=[BB]*/
+/*class: BB:implicit=[BB]*/
 class BB {}
 
 /*element: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_method2_strong.dart b/tests/compiler/dart2js/rti/data/generic_method2_strong.dart
index 1235481..27a1d49 100644
--- a/tests/compiler/dart2js/rti/data/generic_method2_strong.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method2_strong.dart
@@ -13,9 +13,7 @@
   }
 }
 
-// TODO(johnniwinther): Should include 'arg'. Update the 'checkedArguments'
-// computation to take method type arguments into account.
-/*class: BB:checked,implicit=[BB]*/
+/*class: BB:implicit=[BB]*/
 class BB {}
 
 /*class: B:deps=[method1],implicit=[B.T],indirect,needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_method3_strong.dart b/tests/compiler/dart2js/rti/data/generic_method3_strong.dart
index dddc5f0..46ecef3c 100644
--- a/tests/compiler/dart2js/rti/data/generic_method3_strong.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method3_strong.dart
@@ -13,7 +13,7 @@
   }
 }
 
-/*class: BB:arg,checked,implicit=[BB]*/
+/*class: BB:implicit=[BB]*/
 class BB {}
 
 /*element: method2:deps=[B],implicit=[method2.T],indirect,needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/generic_method_is_strong.dart b/tests/compiler/dart2js/rti/data/generic_method_is_strong.dart
index bcd1f4b..db9a3f7 100644
--- a/tests/compiler/dart2js/rti/data/generic_method_is_strong.dart
+++ b/tests/compiler/dart2js/rti/data/generic_method_is_strong.dart
@@ -12,30 +12,29 @@
 
 class B2 {}
 
-/*class: C1:checked,implicit=[C1]*/
+/*class: C1:implicit=[C1]*/
 class C1 {}
 
 class C2 {}
 
-/*class: C3:checked*/
 class C3 {}
 
-/*class: D1:checked,implicit=[D1]*/
+/*class: D1:implicit=[D1]*/
 class D1 {}
 
 class D2 {}
 
-/*class: E1:checked,implicit=[E1]*/
+/*class: E1:implicit=[E1]*/
 class E1 {}
 
 class E2 {}
 
-/*class: F1:checked,implicit=[F1]*/
+/*class: F1:implicit=[F1]*/
 class F1 {}
 
 class F2 {}
 
-/*class: F3:checked,implicit=[F3]*/
+/*class: F3:implicit=[F3]*/
 class F3 {}
 
 /*element: topLevelMethod1:direct,explicit=[topLevelMethod1.T],needsArgs*/
diff --git a/tests/compiler/dart2js/rti/data/list_to_set.dart b/tests/compiler/dart2js/rti/data/list_to_set.dart
index b8598de..f858a43 100644
--- a/tests/compiler/dart2js/rti/data/list_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/list_to_set.dart
@@ -2,8 +2,10 @@
 // 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.
 
-/*class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin,SubListIterable],explicit=[List],implicit=[List.E],indirect,needsArgs*/
-/*class: global#JSArray:checked,deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
+/*ast.class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin,SubListIterable],explicit=[List],implicit=[List.E],indirect,needsArgs*/
+/*kernel.class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin],explicit=[List],implicit=[List.E],indirect,needsArgs*/
+/*ast.class: global#JSArray:deps=[List],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
+/*kernel.class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
 
 main() {
   var c = new Class<int>();
diff --git a/tests/compiler/dart2js/rti/data/map_literal.dart b/tests/compiler/dart2js/rti/data/map_literal.dart
index 409bb7d..1643414 100644
--- a/tests/compiler/dart2js/rti/data/map_literal.dart
+++ b/tests/compiler/dart2js/rti/data/map_literal.dart
@@ -5,7 +5,7 @@
 /*class: global#Map:*/
 /*class: global#LinkedHashMap:deps=[Map]*/
 /*class: global#JsLinkedHashMap:deps=[LinkedHashMap]*/
-/*class: global#double:arg,explicit=[double]*/
+/*class: global#double:explicit=[double]*/
 /*class: global#JSDouble:*/
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/map_literal_checked.dart b/tests/compiler/dart2js/rti/data/map_literal_checked.dart
index d7534bf..9c6733f 100644
--- a/tests/compiler/dart2js/rti/data/map_literal_checked.dart
+++ b/tests/compiler/dart2js/rti/data/map_literal_checked.dart
@@ -2,10 +2,10 @@
 // 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.
 
-/*class: global#Map:checked,explicit=[Map],indirect,needsArgs*/
-/*class: global#LinkedHashMap:checked,deps=[Map],explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],indirect,needsArgs*/
-/*class: global#JsLinkedHashMap:checked,deps=[LinkedHashMap],direct,explicit=[Iterable<JsLinkedHashMap.K>,JsLinkedHashMap.K,JsLinkedHashMap.V,JsLinkedHashMap<JsLinkedHashMap.K,JsLinkedHashMap.V>,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
-/*class: global#double:arg,checked,explicit=[double],implicit=[double]*/
+/*class: global#Map:explicit=[Map],indirect,needsArgs*/
+/*class: global#LinkedHashMap:deps=[Map],explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],indirect,needsArgs*/
+/*class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[Iterable<JsLinkedHashMap.K>,JsLinkedHashMap.K,JsLinkedHashMap.V,JsLinkedHashMap<JsLinkedHashMap.K,JsLinkedHashMap.V>,void Function(JsLinkedHashMap.K,JsLinkedHashMap.V)],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
+/*class: global#double:explicit=[double],implicit=[double]*/
 /*class: global#JSDouble:*/
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/map_to_set.dart b/tests/compiler/dart2js/rti/data/map_to_set.dart
index 2d8037c..4cfda0e 100644
--- a/tests/compiler/dart2js/rti/data/map_to_set.dart
+++ b/tests/compiler/dart2js/rti/data/map_to_set.dart
@@ -5,7 +5,7 @@
 /*class: global#Map:deps=[Class],needsArgs*/
 /*class: global#LinkedHashMap:deps=[Map],needsArgs*/
 /*class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
-/*class: global#double:arg,explicit=[double]*/
+/*class: global#double:explicit=[double]*/
 /*class: global#JSDouble:*/
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/subtype_named_args.dart b/tests/compiler/dart2js/rti/data/subtype_named_args.dart
index 10e7145..d7014bf 100644
--- a/tests/compiler/dart2js/rti/data/subtype_named_args.dart
+++ b/tests/compiler/dart2js/rti/data/subtype_named_args.dart
@@ -6,30 +6,28 @@
 
 import 'package:expect/expect.dart';
 
-/*ast.class: A:arg,checks=[A,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
-/*kernel.class: A:arg,checks=[A,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*ast.class: A:explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*kernel.class: A:explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
 class A {}
 
-/*class: A1:arg,checks=[A1,Object]*/
 class A1 {}
 
-/*class: A2:arg,checks=[A2,Object]*/
 class A2 {}
 
-/*ast.class: B:arg,checks=[A,A1,A2,B,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
-/*kernel.class: B:arg,checks=[A,A1,A2,B,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*ast.class: B:explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*kernel.class: B:explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
 class B implements A, A1, A2 {}
 
-/*ast.class: C:arg,checks=[A,A1,A2,B,C,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
-/*kernel.class: C:arg,checks=[A,A1,A2,B,C,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*ast.class: C:explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*kernel.class: C:explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
 class C implements B {}
 
-/*ast.class: D:arg,checks=[A,A1,A2,B,C,D,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
-/*kernel.class: D:arg,checks=[A,A1,A2,B,C,D,Object],explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*ast.class: D:explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*kernel.class: D:explicit=[dynamic Function({a:A,b:B,c:C,d:D}),dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
 class D implements C {}
 
-/*ast.class: G:arg,checks=[G,Object],explicit=[dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
-/*kernel.class: G:arg,checks=[G,Object],explicit=[dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*ast.class: G:explicit=[dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
+/*kernel.class: G:explicit=[dynamic Function({f1:dynamic Function({a:A,b:B,c:C,d:D}),f2:dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>}),f3:dynamic Function({v:dynamic,x:dynamic,y:dynamic,z:dynamic})}),dynamic Function({g:G<A,B,C,D>,l:List<List<B>>,m:Map<num,int>})]*/
 class G<T, S, U, W> {}
 
 typedef classesFunc({A a, B b, C c, D d});
diff --git a/tests/compiler/dart2js/rti/data/subtype_named_args1.dart b/tests/compiler/dart2js/rti/data/subtype_named_args1.dart
new file mode 100644
index 0000000..0312132
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/subtype_named_args1.dart
@@ -0,0 +1,97 @@
+// 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.
+
+// From co19/Language/Types/Function_Types/subtype_named_args_t01.
+
+import "package:expect/expect.dart";
+
+class A {}
+
+/*ast.class: B:explicit=[dynamic Function({a:B})]*/
+/*kernel.class: B:explicit=[dynamic Function({a:B}),dynamic Function({f:dynamic Function({a:B})})]*/
+class B implements A {}
+
+/*class: C:explicit=[dynamic Function({c:C})]*/
+class C implements B {}
+
+class D implements C {}
+
+typedef t1({B a});
+typedef t2({C c});
+typedef t3({int i});
+typedef t4({var v});
+typedef t5({Map m});
+typedef t6({Map<int, num> m});
+typedef t7({t1 f});
+typedef t8({Object a});
+
+typedef okWithT1_1({A a});
+typedef okWithT1_2({B a});
+typedef okWithT1_3({C a});
+typedef okWithT1_4({D a});
+
+main() {
+  Expect.isTrue(({A a}) {} is t1);
+  Expect.isTrue(({B a}) {} is t1);
+  Expect.isTrue(({C a}) {} is t1);
+  Expect.isTrue(({D a}) {} is t1);
+  Expect.isTrue(({Object a}) {} is t1);
+  Expect.isTrue(({var a}) {} is t1);
+
+  Expect.isTrue(({A c}) {} is t2);
+  Expect.isTrue(({B c}) {} is t2);
+  Expect.isTrue(({C c}) {} is t2);
+  Expect.isTrue(({D c}) {} is t2);
+  Expect.isTrue(({Object c}) {} is t2);
+  Expect.isTrue(({var c}) {} is t2);
+
+  Expect.isTrue(({num i}) {} is t3);
+  Expect.isTrue(({int i}) {} is t3);
+  Expect.isTrue(({Object i}) {} is t3);
+  Expect.isTrue(({var i}) {} is t3);
+
+  Expect.isTrue(({A v}) {} is t4);
+  Expect.isTrue(({B v}) {} is t4);
+  Expect.isTrue(({C v}) {} is t4);
+  Expect.isTrue(({D v}) {} is t4);
+  Expect.isTrue(({Object v}) {} is t4);
+  Expect.isTrue(({var v}) {} is t4);
+  Expect.isTrue(({num v}) {} is t4);
+  Expect.isTrue(({int v}) {} is t4);
+  Expect.isTrue(({Map v}) {} is t4);
+  Expect.isTrue(({Map<List<Map<List, List<int>>>, List> v}) {} is t4);
+  Expect.isTrue(({List v}) {} is t4);
+  Expect.isTrue(({t8 v}) {} is t4);
+  Expect.isTrue(({t7 v}) {} is t4);
+
+  Expect.isTrue(({Map m}) {} is t5);
+  Expect.isTrue(({Map<List, t8> m}) {} is t5);
+  Expect.isTrue(({Object m}) {} is t5);
+  Expect.isTrue(({var m}) {} is t5);
+  Expect.isTrue(({Map<List, List> m}) {} is t5);
+  Expect.isTrue(({Map<int, t8> m}) {} is t5);
+
+  Expect.isTrue(({Map<num, num> m}) {} is t6);
+  Expect.isTrue(({Map<int, int> m}) {} is t6);
+  Expect.isTrue(({Map m}) {} is t6);
+  Expect.isTrue(({Object m}) {} is t6);
+  Expect.isTrue(({var m}) {} is t6);
+
+  Expect.isTrue(({okWithT1_1 f}) {} is t7);
+  Expect.isTrue(({okWithT1_2 f}) {} is t7);
+  Expect.isTrue(({okWithT1_3 f}) {} is t7);
+  Expect.isTrue(({okWithT1_4 f}) {} is t7);
+
+  Expect.isTrue(({A a}) {} is t8);
+  Expect.isTrue(({B a}) {} is t8);
+  Expect.isTrue(({C a}) {} is t8);
+  Expect.isTrue(({D a}) {} is t8);
+  Expect.isTrue(({Object a}) {} is t8);
+  Expect.isTrue(({var a}) {} is t8);
+  Expect.isTrue(({num a}) {} is t8);
+  Expect.isTrue(({int a}) {} is t8);
+  Expect.isTrue(({Map a}) {} is t8);
+  Expect.isTrue(({Map<List<Map<List, List<int>>>, List> a}) {} is t8);
+  Expect.isTrue(({List a}) {} is t8);
+}
diff --git a/tests/compiler/dart2js/rti/data/type_argument_substitution.dart b/tests/compiler/dart2js/rti/data/type_argument_substitution.dart
index c1e227e..635ad13 100644
--- a/tests/compiler/dart2js/rti/data/type_argument_substitution.dart
+++ b/tests/compiler/dart2js/rti/data/type_argument_substitution.dart
@@ -7,16 +7,14 @@
 
 import 'package:expect/expect.dart';
 
-/*class: K:arg*/
 class K {}
 
-/*class: A:arg,checks=[A],explicit=[X<A<String>>]*/
+/*class: A:explicit=[X<A<String>>]*/
 class A<T> {}
 
-/*class: B:arg,checks=[A]*/
 class B extends A<K> {}
 
-/*class: X:checked,explicit=[X<A<String>>],needsArgs*/
+/*class: X:explicit=[X<A<String>>],needsArgs*/
 class X<T> {}
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/type_literal2.dart b/tests/compiler/dart2js/rti/data/type_literal2.dart
new file mode 100644
index 0000000..a1e3e6b
--- /dev/null
+++ b/tests/compiler/dart2js/rti/data/type_literal2.dart
@@ -0,0 +1,18 @@
+// 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.
+
+/*class: A:deps=[B],exp,needsArgs*/
+class A<T> {
+  method1() => T;
+}
+
+/*class: B:needsArgs*/
+class B<S> {
+  method2() => new A<S>().method1();
+}
+
+main() {
+  var b = new B<int>();
+  b.method2();
+}
diff --git a/tests/compiler/dart2js/rti/emission/arguments.dart b/tests/compiler/dart2js/rti/emission/arguments.dart
new file mode 100644
index 0000000..328e684
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/arguments.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A {}
+
+/*class: B:checks=[]*/
+class B {}
+
+/*class: C:checks=[]*/
+class C<T> {}
+
+@noInline
+test(o) => o is C<A>;
+
+main() {
+  test(new C<A>());
+  test(new C<B>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/call.dart b/tests/compiler/dart2js/rti/emission/call.dart
new file mode 100644
index 0000000..d603eab
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/call.dart
@@ -0,0 +1,19 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[$isFunction]*/
+class A {
+  call() {}
+}
+
+@noInline
+test(o) => o is Function;
+
+main() {
+  Expect.isTrue(test(new A()));
+  Expect.isFalse(test(null));
+}
diff --git a/tests/compiler/dart2js/rti/emission/closure_function.dart b/tests/compiler/dart2js/rti/emission/closure_function.dart
new file mode 100644
index 0000000..82d8712
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/closure_function.dart
@@ -0,0 +1,13 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+@noInline
+test(o) => o is Function;
+
+main() {
+  test(/*checks=[]*/ () {});
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/closure_function_type.dart b/tests/compiler/dart2js/rti/emission/closure_function_type.dart
new file mode 100644
index 0000000..0c7e05b
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/closure_function_type.dart
@@ -0,0 +1,13 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+@noInline
+test(o) => o is Function();
+
+main() {
+  test(/*checks=[]*/ () {});
+  test(/*checks=[]*/ (a) {});
+}
diff --git a/tests/compiler/dart2js/rti/emission/generic_instanceof4.dart b/tests/compiler/dart2js/rti/emission/generic_instanceof4.dart
new file mode 100644
index 0000000..45ab17f
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/generic_instanceof4.dart
@@ -0,0 +1,28 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A<T> {
+  @noInline
+  foo(x) {
+    return x is T;
+  }
+}
+
+/*class: BB:checks=[]*/
+class BB {}
+
+/*class: B:checks=[$isBB]*/
+class B<T> implements BB {
+  @noInline
+  foo() {
+    return new A<T>().foo(new B());
+  }
+}
+
+main() {
+  new B<BB>().foo();
+}
diff --git a/tests/compiler/dart2js/rti/emission/inherited_is.dart b/tests/compiler/dart2js/rti/emission/inherited_is.dart
new file mode 100644
index 0000000..618b16f
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/inherited_is.dart
@@ -0,0 +1,25 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:meta/dart2js.dart';
+
+class A {}
+
+/*class: B:checks=[]*/
+class B implements A {}
+
+/*class: C:checks=[$isA]*/
+class C = Object with B;
+
+/*class: D:checks=[]*/
+class D extends C {}
+
+@noInline
+test(o) => o is A;
+
+main() {
+  Expect.isTrue(test(new D()));
+  Expect.isFalse(test(null));
+}
diff --git a/tests/compiler/dart2js/rti/emission/inherited_is2.dart b/tests/compiler/dart2js/rti/emission/inherited_is2.dart
new file mode 100644
index 0000000..a703a2b
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/inherited_is2.dart
@@ -0,0 +1,25 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:meta/dart2js.dart';
+
+class A {}
+
+/*class: B:checks=[$isA]*/
+class B implements A {}
+
+/*class: C:checks=[]*/
+class C extends B {}
+
+/*class: D:checks=[]*/
+class D extends C {}
+
+@noInline
+test(o) => o is A;
+
+main() {
+  Expect.isTrue(test(new D()));
+  Expect.isFalse(test(null));
+}
diff --git a/tests/compiler/dart2js/rti/emission/list.dart b/tests/compiler/dart2js/rti/emission/list.dart
new file mode 100644
index 0000000..b5d777c
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/list.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: global#JSArray:checks=[$isIterable]*/
+/*class: global#Iterable:*/
+
+/*class: A:checks=[]*/
+class A {}
+
+/*class: B:checks=[]*/
+class B {}
+
+@noInline
+test(o) => o is Iterable<A>;
+
+main() {
+  test(<A>[]);
+  test(<B>[]);
+}
diff --git a/tests/compiler/dart2js/rti/emission/map_literal.dart b/tests/compiler/dart2js/rti/emission/map_literal.dart
new file mode 100644
index 0000000..1b86df4
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/map_literal.dart
@@ -0,0 +1,13 @@
+// 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.
+
+/*class: global#Map:*/
+/*class: global#LinkedHashMap:*/
+/*class: global#JsLinkedHashMap:checks=[]*/
+/*class: global#double:checks=[]*/
+/*class: global#JSDouble:checks=[]*/
+
+main() {
+  <int, double>{}[0] = 0.5;
+}
diff --git a/tests/compiler/dart2js/rti/emission/map_literal_checked.dart b/tests/compiler/dart2js/rti/emission/map_literal_checked.dart
new file mode 100644
index 0000000..bda462b
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/map_literal_checked.dart
@@ -0,0 +1,13 @@
+// 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.
+
+/*class: global#Map:checks=[]*/
+/*class: global#LinkedHashMap:*/
+/*class: global#JsLinkedHashMap:checks=[$isLinkedHashMap]*/
+/*class: global#double:checks=[]*/
+/*class: global#JSDouble:checks=[$isdouble]*/
+
+main() {
+  <int, double>{}[0] = 0.5;
+}
diff --git a/tests/compiler/dart2js/rti/emission/mixin_mixin2.dart b/tests/compiler/dart2js/rti/emission/mixin_mixin2.dart
new file mode 100644
index 0000000..747c430
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/mixin_mixin2.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2013, 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:expect/expect.dart";
+
+/*class: M:checks=[]*/
+class M<T> {
+  t() {
+    return T;
+  }
+}
+
+/*class: A:checks=[]*/
+class A<U> = Object with M<U>;
+
+/*class: B:checks=[]*/
+class B<V> = Object with A<V>;
+
+/*class: C:checks=[$asM]*/
+class C<U> = Object with M<List<U>>;
+
+/*class: D:checks=[$asM]*/
+class D<V> = Object with C<Set<V>>;
+
+/*class: E:checks=[$asM]*/
+class E extends A<num> {}
+
+/*class: F:checks=[$asM]*/
+class F extends B<String> {}
+
+/*class: G:checks=[]*/
+class G<T> extends C<T> {}
+
+/*class: H:checks=[$asM]*/
+class H<T> extends D<Map<String, T>> {}
+
+main() {
+  Expect.equals("num", new E().t().toString());
+  Expect.equals("String", new F().t().toString());
+  Expect.equals("List<bool>", new G<bool>().t().toString());
+  Expect.equals("List<Set<Map<String, int>>>", new H<int>().t().toString());
+}
diff --git a/tests/compiler/dart2js/rti/emission/mixin_mixin4.dart b/tests/compiler/dart2js/rti/emission/mixin_mixin4.dart
new file mode 100644
index 0000000..7d42422
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/mixin_mixin4.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, 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:expect/expect.dart";
+
+class I<T> {}
+
+class J<T> {}
+
+/*class: S:checks=[]*/
+class S<T> {}
+
+/*class: M:checks=[]*/
+class M<T> {
+  t() {
+    return T;
+  }
+}
+
+class A<U, V> = Object with M<Map<U, V>> implements I<V>;
+
+/*class: C:checks=[$asA,$asI,$asJ,$asM,$asS,$isA,$isI,$isJ]*/
+class C<T, K> = S<T> with A<T, List<K>> implements J<K>;
+
+@NoInline()
+test(c) {
+  Expect.equals("Map<int, List<bool>>", c.t().toString());
+  Expect.isTrue(c is I<List<bool>>);
+  Expect.isTrue(c is J<bool>);
+  Expect.isTrue(c is S<int>);
+  Expect.isTrue(c is A<int, List<bool>>);
+  Expect.isTrue(c is M<Map<int, List<bool>>>);
+}
+
+main() {
+  test(new C<int, bool>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/mixin_type_arguments.dart b/tests/compiler/dart2js/rti/emission/mixin_type_arguments.dart
new file mode 100644
index 0000000..6067cef
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/mixin_type_arguments.dart
@@ -0,0 +1,107 @@
+// 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.
+
+import 'package:expect/expect.dart' show Expect;
+
+/*class: A:checks=[]*/
+class A {}
+
+/*class: B:checks=[]*/
+class B {}
+
+/*class: C:checks=[]*/
+class C {}
+
+/*class: D:checks=[]*/
+class D {}
+
+/*class: E:checks=[]*/
+class E {}
+
+/*class: F:checks=[]*/
+class F {}
+
+/*class: M1:checks=[]*/
+class M1<Tm1> {
+  m1() => "M1<$Tm1>";
+}
+
+/*class: M2:checks=[]*/
+class M2<Tm2> {
+  m2() => "M2<$Tm2>";
+}
+
+/*class: M3:checks=[]*/
+class M3<Tm3> {
+  m3() => "M3<$Tm3>";
+}
+
+/*class: M4:checks=[]*/
+class M4<Tm4> {
+  m4() => "M4<$Tm4>";
+}
+
+/*class: M5:checks=[]*/
+class M5<Tm5> {
+  m5() => "M5<$Tm5>";
+}
+
+/*class: C1:checks=[$asM1,$asM2,$asM3,$asM4,$asM5]*/
+class C1 = Object with M1, M2<A>, M3, M4<B>, M5<C>;
+
+/*class: C2:checks=[$asM1,$asM2,$asM3,$asM4,$asM5]*/
+class C2 = Object with M1<A>, M2<B>, M3<C>, M4<D>, M5<E>;
+
+/*class: C3:checks=[$asM1,$asM3,$asM4,$asM5]*/
+class C3<T> = Object with M1<A>, M2<T>, M3, M4, M5<B>;
+
+/*class: C4:checks=[$asM1,$asM2,$asM3,$asM4,$asM5]*/
+class C4 extends Object with M1, M2<A>, M3, M4<B>, M5<C> {}
+
+/*class: C5:checks=[$asM1,$asM2,$asM3,$asM4,$asM5]*/
+class C5 extends Object with M1<A>, M2<B>, M3<C>, M4<D>, M5<E> {}
+
+/*class: C6:checks=[$asM1,$asM3,$asM4,$asM5]*/
+class C6<T> extends Object with M1<A>, M2<T>, M3, M4, M5<B> {}
+
+/*class: C7:checks=[$asM1,$asM2,$asM3,$asM4,$asM5]*/
+class C7 = Object with M1<A>, M2<A>, M3<A>, M4<A>, M5<A>;
+
+/*class: C8:checks=[$asM1,$asM2,$asM3,$asM4,$asM5]*/
+class C8 extends Object with M1<A>, M2<A>, M3<A>, M4<A>, M5<A> {}
+
+/*class: C9:checks=[$asM1,$asM2,$asM3,$asM4,$asM5]*/
+class C9 = Object
+    with M1<List<A>>, M2<List<A>>, M3<List<A>>, M4<List<A>>, M5<List<A>>;
+
+/*class: CA:checks=[$asM1,$asM2,$asM3,$asM4,$asM5]*/
+class CA extends Object
+    with M1<List<A>>, M2<List<A>>, M3<List<A>>, M4<List<A>>, M5<List<A>> {}
+
+trace(x) => "${x.m1()}, ${x.m2()}, ${x.m3()}, ${x.m4()}, ${x.m5()}";
+
+main() {
+  Expect.stringEquals(
+      "M1<dynamic>, M2<A>, M3<dynamic>, M4<B>, M5<C>", trace(new C1()));
+  Expect.stringEquals("M1<A>, M2<B>, M3<C>, M4<D>, M5<E>", trace(new C2()));
+  Expect.stringEquals(
+      "M1<A>, M2<dynamic>, M3<dynamic>, M4<dynamic>, M5<B>", trace(new C3()));
+  Expect.stringEquals(
+      "M1<A>, M2<F>, M3<dynamic>, M4<dynamic>, M5<B>", trace(new C3<F>()));
+  Expect.stringEquals(
+      "M1<dynamic>, M2<A>, M3<dynamic>, M4<B>, M5<C>", trace(new C4()));
+  Expect.stringEquals("M1<A>, M2<B>, M3<C>, M4<D>, M5<E>", trace(new C5()));
+  Expect.stringEquals(
+      "M1<A>, M2<dynamic>, M3<dynamic>, M4<dynamic>, M5<B>", trace(new C6()));
+  Expect.stringEquals(
+      "M1<A>, M2<F>, M3<dynamic>, M4<dynamic>, M5<B>", trace(new C6<F>()));
+  Expect.stringEquals("M1<A>, M2<A>, M3<A>, M4<A>, M5<A>", trace(new C7()));
+  Expect.stringEquals("M1<A>, M2<A>, M3<A>, M4<A>, M5<A>", trace(new C8()));
+  Expect.stringEquals(
+      "M1<List<A>>, M2<List<A>>, M3<List<A>>, M4<List<A>>, M5<List<A>>",
+      trace(new C9()));
+  Expect.stringEquals(
+      "M1<List<A>>, M2<List<A>>, M3<List<A>>, M4<List<A>>, M5<List<A>>",
+      trace(new CA()));
+}
diff --git a/tests/compiler/dart2js/rti/emission/native.dart b/tests/compiler/dart2js/rti/emission/native.dart
new file mode 100644
index 0000000..c7bfb9f
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/native.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2015, 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:expect/expect.dart";
+// ignore: import_internal_library
+import 'dart:_js_helper' show Native;
+// ignore: import_internal_library
+import 'dart:_foreign_helper' show JS;
+
+/*class: Purple:checks=[$isPurple]*/
+@Native('PPPP')
+class Purple {}
+
+@Native('QQQQ')
+class Q {}
+
+@NoInline()
+makeP() => JS('returns:;creates:Purple', 'null');
+
+@NoInline()
+makeQ() => JS('Q', 'null');
+
+@NoInline()
+testNative() {
+  var x = makeP();
+  Expect.isTrue(x is Purple);
+  x = makeQ();
+  Expect.isFalse(x is Purple);
+}
+
+main() {
+  testNative();
+}
diff --git a/tests/compiler/dart2js/rti/emission/regress_18713.dart b/tests/compiler/dart2js/rti/emission/regress_18713.dart
new file mode 100644
index 0000000..8d0ff99
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/regress_18713.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2016, 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:expect/expect.dart";
+
+/*class: T:checks=[]*/
+class T<X> {
+  final Type tType = X;
+  Type get getTType => X;
+}
+
+/*class: S:checks=[]*/
+class S<Y> {
+  final Type sType = Y;
+  Type get getSType => Y;
+}
+
+/*class: TS:checks=[$asS0,$asT]*/
+class TS<A, B> = T<A> with S<B>;
+
+@NoInline()
+@AssumeDynamic()
+dyn(x) => x;
+
+main() {
+  var ts = new TS<int, String>();
+
+  Expect.equals("String", ts.sType.toString());
+  Expect.equals("int", ts.tType.toString());
+  Expect.equals("String", ts.getSType.toString());
+  Expect.equals("int", ts.getTType.toString());
+
+  Expect.equals("String", dyn(ts).sType.toString());
+  Expect.equals("int", dyn(ts).tType.toString());
+  Expect.equals("String", dyn(ts).getSType.toString());
+  Expect.equals("int", dyn(ts).getTType.toString());
+}
diff --git a/tests/compiler/dart2js/rti/emission/runtime_type.dart b/tests/compiler/dart2js/rti/emission/runtime_type.dart
new file mode 100644
index 0000000..c9973eb
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/runtime_type.dart
@@ -0,0 +1,13 @@
+// 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.
+
+/*class: A:checks=[]*/
+class A<T> {}
+
+/*class: B:checks=[]*/
+class B<T> {}
+
+main() {
+  print("A<B<int>>" == new A<B<int>>().runtimeType.toString());
+}
diff --git a/tests/compiler/dart2js/rti/emission/self.dart b/tests/compiler/dart2js/rti/emission/self.dart
new file mode 100644
index 0000000..76c29c4
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/self.dart
@@ -0,0 +1,16 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: C:checks=[]*/
+class C {}
+
+@noInline
+test(o) => o is C;
+
+main() {
+  test(new C());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/self_generic.dart b/tests/compiler/dart2js/rti/emission/self_generic.dart
new file mode 100644
index 0000000..793f276
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/self_generic.dart
@@ -0,0 +1,16 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: C:checks=[]*/
+class C<T> {}
+
+@noInline
+test(o) => o is C<String>;
+
+main() {
+  test(new C<String>());
+  test(new C<int>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/subtype_named_args.dart b/tests/compiler/dart2js/rti/emission/subtype_named_args.dart
new file mode 100644
index 0000000..b2b1cc7
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/subtype_named_args.dart
@@ -0,0 +1,80 @@
+// 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.
+
+// From co19/Language/Types/Function_Types/subtype_named_args_t02.
+
+import 'package:expect/expect.dart';
+
+/*class: A:checks=[]*/
+class A {}
+
+/*class: A1:checks=[]*/
+class A1 {}
+
+/*class: A2:checks=[]*/
+class A2 {}
+
+/*class: B:checks=[$isA,$isA1,$isA2]*/
+class B implements A, A1, A2 {}
+
+/*class: C:checks=[$isA,$isA1,$isA2,$isB]*/
+class C implements B {}
+
+/*class: D:checks=[$isA,$isA1,$isA2,$isB,$isC]*/
+class D implements C {}
+
+/*class: G:checks=[]*/
+class G<T, S, U, W> {}
+
+typedef classesFunc({A a, B b, C c, D d});
+typedef genericsFunc({Map<num, int> m, List<List<B>> l, G<A, B, C, D> g});
+typedef dynamicFunc({var x, var y, var z, var v});
+typedef funcFunc({classesFunc f1, genericsFunc f2, dynamicFunc f3});
+typedef mixFunc({var x, B b, G<A, B, C, D> g, funcFunc f});
+
+typedef okWithClassesFunc_1({A a, A1 b, A1 c, A1 d});
+typedef okWithClassesFunc_2({D a, D b, D c, D d});
+
+typedef okWithGenericsFunc_1(
+    {Map<num, num> m, List<List<A1>> l, G<A, A1, A1, A1> g});
+typedef okWithGenericsFunc_2(
+    {Map<int, int> m, List<List<D>> l, G<D, D, D, D> g});
+
+typedef okWithDynamicFunc_1({A x, G y, mixFunc z, var v});
+typedef okWithDynamicFunc_2({int x, bool y, List<Map> z, classesFunc v});
+
+main() {
+  Expect.isTrue(/*checks=[]*/ ({D a, B b, C c, A d}) {} is classesFunc);
+  Expect.isTrue(/*checks=[]*/ ({A a, A b, A c, A d}) {} is classesFunc);
+  Expect.isTrue(/*checks=[]*/ ({D a, A1 b, A1 c, A1 d}) {} is classesFunc);
+  Expect.isTrue(/*checks=[]*/ ({D a, A2 b, A2 c, A2 d}) {} is classesFunc);
+  Expect.isTrue(/*checks=[]*/ ({D a, D b, D c, D d}) {} is classesFunc);
+  Expect.isTrue(/*checks=[]*/ ({var a, var b, var c, var d}) {} is classesFunc);
+  Expect.isTrue(/*checks=[]*/ ({Object a, Object b, Object c, Object d}) {}
+      is classesFunc);
+
+  Expect.isTrue(/*checks=[]*/ (
+      {Map<num, num> m,
+      List<List<A1>> l,
+      G<A, A1, A1, A1> g}) {} is genericsFunc);
+  Expect.isTrue(
+      /*checks=[]*/ ({Map<int, int> m, List<List<D>> l, G<D, D, D, D> g}) {}
+          is genericsFunc);
+  Expect.isTrue(/*checks=[]*/ ({var m, var l, var g}) {} is genericsFunc);
+  Expect.isTrue(
+      /*checks=[]*/ ({Object m, Object l, Object g}) {} is genericsFunc);
+
+  Expect.isTrue(/*checks=[]*/ ({A x, G y, mixFunc z, var v}) {} is dynamicFunc);
+  Expect.isTrue(/*checks=[]*/ ({int x, bool y, List<Map> z, classesFunc v}) {}
+      is dynamicFunc);
+
+  Expect.isTrue(/*checks=[]*/ (
+      {okWithClassesFunc_1 f1,
+      okWithGenericsFunc_1 f2,
+      okWithDynamicFunc_1 f3}) {} is funcFunc);
+  Expect.isTrue(/*checks=[]*/ (
+      {okWithClassesFunc_2 f1,
+      okWithGenericsFunc_2 f2,
+      okWithDynamicFunc_2 f3}) {} is funcFunc);
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclass.dart b/tests/compiler/dart2js/rti/emission/superclass.dart
new file mode 100644
index 0000000..4270537
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclass.dart
@@ -0,0 +1,19 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: B:checks=[]*/
+class B {}
+
+/*class: C:checks=[]*/
+class C extends B {}
+
+@noInline
+test(o) => o is B;
+
+main() {
+  test(new C());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclass_as.dart b/tests/compiler/dart2js/rti/emission/superclass_as.dart
new file mode 100644
index 0000000..e780a0e
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclass_as.dart
@@ -0,0 +1,26 @@
+// 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.
+
+import 'package:expect/expect.dart';
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A<T> {}
+
+/*class: B:checks=[]*/
+class B<T, S> {
+  @noInline
+  method() => new A<S>();
+}
+
+/*class: C:checks=[$asB]*/
+class C<T> extends B<T, T> {}
+
+@noInline
+test(o) => o is A<int>;
+
+main() {
+  Expect.isTrue(test(new C<int>().method()));
+  Expect.isFalse(test(new C<String>().method()));
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclass_complex.dart b/tests/compiler/dart2js/rti/emission/superclass_complex.dart
new file mode 100644
index 0000000..d2f9bb5
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclass_complex.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A<T> {}
+
+/*class: B:checks=[]*/
+class B<T> {}
+
+/*class: C:checks=[$asB]*/
+class C<T> extends B<A<T>> {}
+
+@noInline
+test(o) => o is B<A<String>>;
+
+main() {
+  test(new C<String>());
+  test(new C<int>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclass_fixed.dart b/tests/compiler/dart2js/rti/emission/superclass_fixed.dart
new file mode 100644
index 0000000..5c86698
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclass_fixed.dart
@@ -0,0 +1,19 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: B:checks=[]*/
+class B<T> {}
+
+/*class: C:checks=[$asB]*/
+class C extends B<String> {}
+
+@noInline
+test(o) => o is B<String>;
+
+main() {
+  test(new C());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclass_supertype.dart b/tests/compiler/dart2js/rti/emission/superclass_supertype.dart
new file mode 100644
index 0000000..fa9bad0
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclass_supertype.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A {}
+
+/*class: B:*/
+class B {}
+
+/*class: C:checks=[$isB]*/
+class C extends A implements B {}
+
+@noInline
+test(o) => o is B;
+
+main() {
+  test(new C());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclass_supertype_complex.dart b/tests/compiler/dart2js/rti/emission/superclass_supertype_complex.dart
new file mode 100644
index 0000000..29bcaa7
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclass_supertype_complex.dart
@@ -0,0 +1,25 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A<T> {}
+
+/*class: B:*/
+class B<T> {}
+
+/*class: C:checks=[]*/
+class C<T> {}
+
+/*class: D:checks=[$asB,$isB]*/
+class D<T> extends C<T> implements B<A<T>> {}
+
+@noInline
+test(o) => o is B<A<String>>;
+
+main() {
+  test(new D<String>());
+  test(new D<int>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclass_supertype_fixed.dart b/tests/compiler/dart2js/rti/emission/superclass_supertype_fixed.dart
new file mode 100644
index 0000000..3c5a8d0
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclass_supertype_fixed.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A {}
+
+/*class: B:*/
+class B<T> {}
+
+/*class: C:checks=[$asB,$isB]*/
+class C extends A implements B<String> {}
+
+@noInline
+test(o) => o is B<String>;
+
+main() {
+  test(new C());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclass_supertype_trivial.dart b/tests/compiler/dart2js/rti/emission/superclass_supertype_trivial.dart
new file mode 100644
index 0000000..73f6b8b
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclass_supertype_trivial.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A<T> {}
+
+/*class: B:*/
+class B<T> {}
+
+/*class: C:checks=[$isB]*/
+class C<T> extends A<T> implements B<T> {}
+
+@noInline
+test(o) => o is B<String>;
+
+main() {
+  test(new C<String>());
+  test(new C<int>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclass_trivial.dart b/tests/compiler/dart2js/rti/emission/superclass_trivial.dart
new file mode 100644
index 0000000..b9d8ac1
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclass_trivial.dart
@@ -0,0 +1,19 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: B:checks=[]*/
+class B<T> {}
+
+/*class: C:checks=[]*/
+class C<T> extends B<T> {}
+
+@noInline
+test(o) => o is B<String>;
+
+main() {
+  test(new C<String>());
+  test(new C<int>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclasses_non_trivial.dart b/tests/compiler/dart2js/rti/emission/superclasses_non_trivial.dart
new file mode 100644
index 0000000..c3ff5dd
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclasses_non_trivial.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A<T> {}
+
+/*class: B:checks=[$asA]*/
+class B<S, T> extends A<T> {} // Non-trivial substitution of A.
+
+/*class: C:checks=[]*/
+class C<S, T> extends B<S, T> {} // Non-trivial substitution of A
+
+@noInline
+test(o) => o is A<String>;
+
+main() {
+  test(new C<int, String>());
+  test(new B<String, int>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/superclasses_trivial.dart b/tests/compiler/dart2js/rti/emission/superclasses_trivial.dart
new file mode 100644
index 0000000..a552926
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/superclasses_trivial.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A<T> {}
+
+/*class: B:checks=[$asA]*/
+class B<S, T> extends A<T> {} // Non-trivial substitution of A.
+
+/*class: C:checks=[$asA,$asB]*/
+class C<T> extends B<T, T> {} // Trivial substitution of A
+
+@noInline
+test(o) => o is A<String>;
+
+main() {
+  test(new C<String>());
+  test(new B<String, int>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/supertype.dart b/tests/compiler/dart2js/rti/emission/supertype.dart
new file mode 100644
index 0000000..763d175
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/supertype.dart
@@ -0,0 +1,19 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: B:*/
+class B {}
+
+/*class: C:checks=[$isB]*/
+class C implements B {}
+
+@noInline
+test(o) => o is B;
+
+main() {
+  test(new C());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/supertype_complex.dart b/tests/compiler/dart2js/rti/emission/supertype_complex.dart
new file mode 100644
index 0000000..8a70382
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/supertype_complex.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A<T> {}
+
+/*class: B:*/
+class B<T> {}
+
+/*class: C:checks=[$asB,$isB]*/
+class C<T> implements B<A<T>> {}
+
+@noInline
+test(o) => o is B<A<String>>;
+
+main() {
+  test(new C<String>());
+  test(new C<int>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/supertype_fixed.dart b/tests/compiler/dart2js/rti/emission/supertype_fixed.dart
new file mode 100644
index 0000000..ce5d6d7
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/supertype_fixed.dart
@@ -0,0 +1,19 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: B:*/
+class B<T> {}
+
+/*class: C:checks=[$asB,$isB]*/
+class C implements B<String> {}
+
+@noInline
+test(o) => o is B<String>;
+
+main() {
+  test(new C());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/supertype_trivial.dart b/tests/compiler/dart2js/rti/emission/supertype_trivial.dart
new file mode 100644
index 0000000..4cc95f5
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/supertype_trivial.dart
@@ -0,0 +1,19 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: B:*/
+class B<T> {}
+
+/*class: C:checks=[$isB]*/
+class C<T> implements B<T> {}
+
+@noInline
+test(o) => o is B<String>;
+
+main() {
+  test(new C<String>());
+  test(new C<int>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/supertypes_extends.dart b/tests/compiler/dart2js/rti/emission/supertypes_extends.dart
new file mode 100644
index 0000000..ab679a8
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/supertypes_extends.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:*/
+class A {}
+
+/*class: B:checks=[$isA]*/
+class B implements A {}
+
+/*class: C:checks=[]*/
+class C extends B {} // Implements A through `extends B`.
+
+@noInline
+test(o) => o is A;
+
+main() {
+  test(new C());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/supertypes_extends2.dart b/tests/compiler/dart2js/rti/emission/supertypes_extends2.dart
new file mode 100644
index 0000000..772ef53
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/supertypes_extends2.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+class A {}
+
+/*class: B:checks=[$isA]*/
+class B implements A {}
+
+/*class: C:checks=[]*/
+class C extends B {} // Implements A through `extends B`.
+
+@noInline
+test(o) => o is A;
+
+main() {
+  test(new C());
+  test(new B());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/supertypes_extends3.dart b/tests/compiler/dart2js/rti/emission/supertypes_extends3.dart
new file mode 100644
index 0000000..894e130
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/supertypes_extends3.dart
@@ -0,0 +1,25 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:*/
+class A {}
+
+/*class: B:checks=[$isA]*/
+class B implements A {}
+
+/*class: C:checks=[]*/
+class C extends B {} // Implements A through `extends B`.
+
+/*class: D:checks=[]*/
+class D extends C {} // Implements A through `extends C`.
+
+@noInline
+test(o) => o is A;
+
+main() {
+  test(new D());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/supertypes_implements.dart b/tests/compiler/dart2js/rti/emission/supertypes_implements.dart
new file mode 100644
index 0000000..ac984b7
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/supertypes_implements.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:*/
+class A {}
+
+/*class: B:*/
+class B extends A {}
+
+/*class: C:checks=[$isA]*/
+class C implements B {} // Implements A through `implements B`.
+
+@noInline
+test(o) => o is A;
+
+main() {
+  test(new C());
+  test(null);
+}
diff --git a/tests/compiler/dart2js/rti/emission/supertypes_non_trivial.dart b/tests/compiler/dart2js/rti/emission/supertypes_non_trivial.dart
new file mode 100644
index 0000000..27fd588
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/supertypes_non_trivial.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A<T> {}
+
+/*class: B:checks=[$asA]*/
+class B<S, T> extends A<T> {} // Non-trivial substitution of A.
+
+/*class: C:checks=[$asA,$isA]*/
+class C<S, T> implements B<S, T> {} // Non-trivial substitution of A
+
+@noInline
+test(o) => o is A<String>;
+
+main() {
+  test(new C<int, String>());
+  test(new B<String, int>());
+}
diff --git a/tests/compiler/dart2js/rti/emission/supertypes_trivial.dart b/tests/compiler/dart2js/rti/emission/supertypes_trivial.dart
new file mode 100644
index 0000000..340c2f4
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/supertypes_trivial.dart
@@ -0,0 +1,22 @@
+// 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.
+
+import 'package:meta/dart2js.dart';
+
+/*class: A:checks=[]*/
+class A<T> {}
+
+/*class: B:checks=[$asA]*/
+class B<S, T> extends A<T> {} // Non-trivial substitution of A.
+
+/*class: C:checks=[$isA]*/
+class C<T> implements B<T, T> {} // Trivial substitution of A
+
+@noInline
+test(o) => o is A<String>;
+
+main() {
+  test(new C<String>());
+  test(new B<String, int>());
+}
diff --git a/tests/compiler/dart2js/rti/rti_emission_test.dart b/tests/compiler/dart2js/rti/rti_emission_test.dart
new file mode 100644
index 0000000..2dcdc43
--- /dev/null
+++ b/tests/compiler/dart2js/rti/rti_emission_test.dart
@@ -0,0 +1,207 @@
+// 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.
+
+import 'dart:io';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/closure.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
+import 'package:compiler/src/elements/elements.dart';
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/js_emitter/model.dart';
+import 'package:compiler/src/tree/nodes.dart' as ast;
+import 'package:compiler/src/kernel/element_map.dart';
+import 'package:compiler/src/kernel/kernel_backend_strategy.dart';
+import 'package:compiler/src/ssa/builder.dart' as ast;
+import 'package:kernel/ast.dart' as ir;
+import '../equivalence/id_equivalence.dart';
+import '../equivalence/id_equivalence_helper.dart';
+import '../helpers/program_lookup.dart';
+
+main(List<String> args) {
+  asyncTest(() async {
+    Directory dataDir =
+        new Directory.fromUri(Platform.script.resolve('emission'));
+    await checkTests(
+        dataDir, computeAstRtiMemberEmission, computeKernelRtiMemberEmission,
+        computeClassDataFromAst: computeAstRtiClassEmission,
+        computeClassDataFromKernel: computeKernelRtiClassEmission,
+        args: args,
+        options: [
+          Flags.strongMode
+        ],
+        skipForKernel: [
+          // TODO(johnniwinther): Fix this. It triggers a crash in the ssa
+          // builder.
+          'runtime_type.dart',
+        ]);
+  });
+}
+
+class Tags {
+  static const String isChecks = 'checks';
+}
+
+void computeAstRtiMemberEmission(
+    Compiler compiler, MemberEntity _member, Map<Id, ActualData> actualMap,
+    {bool verbose: false}) {
+  MemberElement member = _member;
+  ResolvedAst resolvedAst = member.resolvedAst;
+  compiler.reporter.withCurrentElement(member.implementation, () {
+    new RtiMemberEmissionAstComputer(
+            compiler.reporter, actualMap, resolvedAst, compiler)
+        .run();
+  });
+}
+
+void computeAstRtiClassEmission(
+    Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
+    {bool verbose: false}) {
+  new RtiClassEmissionAstComputer(compiler, actualMap).computeClassValue(cls);
+}
+
+abstract class ComputeValueMixin<T> {
+  Compiler get compiler;
+  ProgramLookup lookup;
+
+  String getClassValue(ClassEntity element) {
+    lookup ??= new ProgramLookup(compiler);
+    Class cls = lookup.getClass(element);
+    Features features = new Features();
+    if (cls != null) {
+      features.addElement(Tags.isChecks);
+      for (StubMethod stub in cls.isChecks) {
+        features.addElement(Tags.isChecks, stub.name.key);
+      }
+    }
+    return features.getText();
+  }
+
+  String getMemberValue(MemberEntity member) {
+    if (member.enclosingClass != null && member.enclosingClass.isClosure) {
+      return getClassValue(member.enclosingClass);
+    }
+    return null;
+  }
+}
+
+class RtiClassEmissionAstComputer extends DataRegistry
+    with ComputeValueMixin<ast.Node> {
+  final Compiler compiler;
+  final Map<Id, ActualData> actualMap;
+
+  RtiClassEmissionAstComputer(this.compiler, this.actualMap);
+
+  DiagnosticReporter get reporter => compiler.reporter;
+
+  void computeClassValue(covariant ClassElement cls) {
+    Id id = new ClassId(cls.name);
+    registerValue(cls.sourcePosition, id, getClassValue(cls), cls);
+  }
+}
+
+class RtiMemberEmissionAstComputer extends AstDataExtractor
+    with ComputeValueMixin<ast.Node> {
+  final Compiler compiler;
+
+  RtiMemberEmissionAstComputer(DiagnosticReporter reporter,
+      Map<Id, ActualData> actualMap, ResolvedAst resolvedAst, this.compiler)
+      : super(reporter, actualMap, resolvedAst);
+
+  @override
+  String computeElementValue(Id id, AstElement element) {
+    if (element.isParameter) {
+      return null;
+    } else if (element.isLocal && element.isFunction) {
+      LocalFunctionElement localFunction = element;
+      return getMemberValue(localFunction.callMethod);
+    } else {
+      MemberElement member = element.declaration;
+      return getMemberValue(member);
+    }
+  }
+
+  @override
+  String computeNodeValue(Id id, ast.Node node, [AstElement element]) {
+    if (element != null && element.isLocal && element.isFunction) {
+      return computeElementValue(id, element);
+    }
+    return null;
+  }
+}
+
+void computeKernelRtiMemberEmission(
+    Compiler compiler, MemberEntity member, Map<Id, ActualData> actualMap,
+    {bool verbose: false}) {
+  KernelBackendStrategy backendStrategy = compiler.backendStrategy;
+  KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+  MemberDefinition definition = elementMap.getMemberDefinition(member);
+  new RtiMemberEmissionIrComputer(
+          compiler.reporter,
+          actualMap,
+          elementMap,
+          member,
+          compiler,
+          backendStrategy.closureDataLookup as ClosureDataLookup<ir.Node>)
+      .run(definition.node);
+}
+
+void computeKernelRtiClassEmission(
+    Compiler compiler, ClassEntity cls, Map<Id, ActualData> actualMap,
+    {bool verbose: false}) {
+  KernelBackendStrategy backendStrategy = compiler.backendStrategy;
+  KernelToElementMapForBuilding elementMap = backendStrategy.elementMap;
+  new RtiClassEmissionIrComputer(compiler, elementMap, actualMap)
+      .computeClassValue(cls);
+}
+
+class RtiClassEmissionIrComputer extends DataRegistry
+    with ComputeValueMixin<ir.Node> {
+  final Compiler compiler;
+  final KernelToElementMapForBuilding _elementMap;
+  final Map<Id, ActualData> actualMap;
+
+  RtiClassEmissionIrComputer(this.compiler, this._elementMap, this.actualMap);
+
+  DiagnosticReporter get reporter => compiler.reporter;
+
+  void computeClassValue(ClassEntity cls) {
+    Id id = new ClassId(cls.name);
+    ir.TreeNode node = _elementMap.getClassDefinition(cls).node;
+    registerValue(
+        computeSourceSpanFromTreeNode(node), id, getClassValue(cls), cls);
+  }
+}
+
+class RtiMemberEmissionIrComputer extends IrDataExtractor
+    with ComputeValueMixin<ir.Node> {
+  final KernelToElementMapForBuilding _elementMap;
+  final ClosureDataLookup<ir.Node> _closureDataLookup;
+  final Compiler compiler;
+
+  RtiMemberEmissionIrComputer(
+      DiagnosticReporter reporter,
+      Map<Id, ActualData> actualMap,
+      this._elementMap,
+      MemberEntity member,
+      this.compiler,
+      this._closureDataLookup)
+      : super(reporter, actualMap);
+
+  @override
+  String computeMemberValue(Id id, ir.Member node) {
+    return getMemberValue(_elementMap.getMember(node));
+  }
+
+  @override
+  String computeNodeValue(Id id, ir.TreeNode node) {
+    if (node is ir.FunctionExpression || node is ir.FunctionDeclaration) {
+      ClosureRepresentationInfo info = _closureDataLookup.getClosureInfo(node);
+      return getMemberValue(info.callMethod);
+    }
+    return null;
+  }
+}
diff --git a/tests/compiler/dart2js/rti/rti_need_test.dart b/tests/compiler/dart2js/rti/rti_need_test.dart
index 75a94d4..1acbf8f 100644
--- a/tests/compiler/dart2js/rti/rti_need_test.dart
+++ b/tests/compiler/dart2js/rti/rti_need_test.dart
@@ -34,7 +34,14 @@
         computeClassDataFromAst: computeAstRtiClassNeed,
         computeClassDataFromKernel: computeKernelRtiClassNeed,
         args: args,
-        options: [Flags.strongMode]);
+        options: [
+          Flags.strongMode
+        ],
+        skipForKernel: [
+          // TODO(johnniwinther): Fix this. It triggers a crash in the ssa
+          // builder.
+          'generic_creation.dart',
+        ]);
   });
 }
 
@@ -71,23 +78,6 @@
   static const String directTypeArgumentTest = 'direct';
   static const String indirectTypeArgumentTest = 'indirect';
   static const String typeLiteral = 'exp';
-  static const String typeChecks = 'checks';
-
-  /// This class is needed as a checked type argument.
-  ///
-  /// For instance directly in `String` in `o is List<String>` or indirectly
-  /// as `String` in
-  ///
-  ///   class C<T> {
-  ///     method(o) => o is T;
-  ///   }
-  ///   main() => new C<String>().method('');
-  static const String argumentClass = 'arg';
-
-  // Objects are checked against this class.
-  //
-  // For instance `String` in `o is String`.
-  static const String checkedClass = 'checked';
 }
 
 abstract class ComputeValueMixin<T> {
@@ -98,9 +88,6 @@
   RuntimeTypesNeedBuilderImpl get rtiNeedBuilder =>
       compiler.frontendStrategy.runtimeTypesNeedBuilderForTesting;
   RuntimeTypesNeed get rtiNeed => compiler.backendClosedWorldForTesting.rtiNeed;
-  RuntimeTypesChecks get rtiChecks =>
-      compiler.backend.emitter.typeTestRegistry.rtiChecks;
-  TypeChecks get requiredChecks => rtiChecks.requiredChecks;
   ClassEntity getFrontendClass(ClassEntity cls);
   MemberEntity getFrontendMember(MemberEntity member);
   Local getFrontendClosure(MemberEntity member);
@@ -152,17 +139,6 @@
         rtiNeedBuilder.typeVariableTests.explicitIsChecks);
     findChecks(features, Tags.implicitTypeCheck, frontendClass,
         rtiNeedBuilder.typeVariableTests.implicitIsChecks);
-    if (rtiChecks.checkedClasses.contains(backendClass)) {
-      features.add(Tags.checkedClass);
-    }
-    if (rtiChecks.getRequiredArgumentClasses().contains(backendClass)) {
-      features.add(Tags.argumentClass);
-    }
-    Iterable<TypeCheck> checks = requiredChecks[backendClass];
-    if (checks.isNotEmpty) {
-      features[Tags.typeChecks] =
-          '[${(checks.map((c) => c.cls.name).toList()..sort()).join(',')}]';
-    }
     return features.getText();
   }
 
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index 4f5250d..5047aea 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -250,7 +250,6 @@
 symbol_reserved_word_test/03: RuntimeError
 type_hashcode_test: Crash # Assertion failure: Only 2 of 3 arguments have been read from: [HRef(HForeignCode("# ? Object.keys(#) : []")), literal: NullConstant, literal: NullConstant]
 uri_base_test: RuntimeError
-uri_query_test: Crash # Assertion failure: Cannot find value local(testQueryParameters#normalizedQuery) in (BoxLocal(_box_0)) for j:signature(testQueryParameters_test.$signature).
 
 [ $compiler == dart2js && $dart2js_with_kernel && $minified && $strong ]
 apply3_test: CompileTimeError
@@ -293,7 +292,6 @@
 symbol_operator_test/none: RuntimeError
 symbol_reserved_word_test/03: RuntimeError
 uri_base_test: RuntimeError
-uri_query_test: Crash # Assertion failure: Cannot find value local(testQueryParameters#normalizedQuery) in (BoxLocal(_box_0)) for j:signature(testQueryParameters_test.$signature).
 
 [ $compiler == dart2js && $dart2js_with_kernel && !$strong ]
 *: SkipByDesign
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 368ba6a..f4ca4f4 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -277,8 +277,6 @@
 mixin_illegal_superclass_test/29: MissingCompileTimeError
 mixin_illegal_superclass_test/30: MissingCompileTimeError
 mixin_issue10216_2_test: RuntimeError
-mixin_mixin2_test: RuntimeError
-mixin_mixin3_test: RuntimeError
 mixin_mixin4_test: RuntimeError
 mixin_mixin5_test: RuntimeError
 mixin_mixin6_test: RuntimeError
@@ -286,7 +284,6 @@
 mixin_mixin_bound2_test: RuntimeError
 mixin_mixin_bound_test: RuntimeError
 mixin_mixin_test: RuntimeError
-mixin_mixin_type_arguments_test: Crash # NoSuchMethodError: The method 'hasSubclass' was called on null.
 mixin_of_mixin_test/01: CompileTimeError
 mixin_of_mixin_test/02: CompileTimeError
 mixin_of_mixin_test/03: CompileTimeError
@@ -642,8 +639,6 @@
 mixin_illegal_superclass_test/29: MissingCompileTimeError
 mixin_illegal_superclass_test/30: MissingCompileTimeError
 mixin_issue10216_2_test: RuntimeError
-mixin_mixin2_test: RuntimeError
-mixin_mixin3_test: RuntimeError
 mixin_mixin4_test: RuntimeError
 mixin_mixin5_test: RuntimeError
 mixin_mixin6_test: RuntimeError
@@ -651,7 +646,6 @@
 mixin_mixin_bound2_test: RuntimeError
 mixin_mixin_bound_test: RuntimeError
 mixin_mixin_test: RuntimeError
-mixin_mixin_type_arguments_test: RuntimeError
 mixin_of_mixin_test/01: CompileTimeError
 mixin_of_mixin_test/02: CompileTimeError
 mixin_of_mixin_test/03: CompileTimeError
@@ -949,9 +943,6 @@
 mixin_illegal_superclass_test/28: MissingCompileTimeError
 mixin_illegal_superclass_test/29: MissingCompileTimeError
 mixin_illegal_superclass_test/30: MissingCompileTimeError
-mixin_mixin2_test: RuntimeError
-mixin_mixin3_test: RuntimeError
-mixin_mixin_type_arguments_test: RuntimeError
 mixin_of_mixin_test/01: CompileTimeError
 mixin_of_mixin_test/02: CompileTimeError
 mixin_of_mixin_test/03: CompileTimeError
@@ -1259,7 +1250,6 @@
 mixin_illegal_superclass_test/28: MissingCompileTimeError
 mixin_illegal_superclass_test/29: MissingCompileTimeError
 mixin_illegal_superclass_test/30: MissingCompileTimeError
-mixin_mixin_type_arguments_test: RuntimeError
 mixin_of_mixin_test/01: CompileTimeError
 mixin_of_mixin_test/02: CompileTimeError
 mixin_of_mixin_test/03: CompileTimeError
@@ -1460,9 +1450,6 @@
 mixin_forwarding_constructor4_test/01: MissingCompileTimeError # Issue 15101
 mixin_forwarding_constructor4_test/02: MissingCompileTimeError # Issue 15101
 mixin_forwarding_constructor4_test/03: MissingCompileTimeError # Issue 15101
-mixin_mixin2_test: RuntimeError # Issue 13109.
-mixin_mixin3_test: RuntimeError # Issue 13109.
-mixin_mixin_type_arguments_test: RuntimeError # Issue 29587
 mixin_of_mixin_test: CompileTimeError # Issue 23773
 mixin_super_2_test: CompileTimeError # Issue 23773
 mixin_super_bound2_test: CompileTimeError # Issue 23773
@@ -1585,18 +1572,19 @@
 symbol_conflict_test: RuntimeError # Issue 23857
 
 [ $compiler == dart2js && $minified ]
-cyclic_type2_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-cyclic_type_test/0*: RuntimeError, OK # runtimeType.toString not preserved in minified code. 
-f_bounded_quantification4_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-generic_closure_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-mixin_generic_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-mixin_mixin2_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-mixin_mixin3_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-mixin_mixin4_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-mixin_mixin5_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-mixin_mixin6_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-mixin_mixin_bound2_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-mixin_mixin_bound_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
-regress_21795_test: RuntimeError, OK # runtimeType.toString not preserved in minified code.
+cyclic_type2_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+cyclic_type_test/0*: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+f_bounded_quantification4_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+generic_closure_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+mixin_generic_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+mixin_mixin2_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+mixin_mixin3_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+mixin_mixin4_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+mixin_mixin5_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+mixin_mixin6_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+mixin_mixin_bound2_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+mixin_mixin_bound_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+mixin_mixin_type_arguments_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
+regress_21795_test: RuntimeError, OK # Issue 31054: runtimeType.toString not preserved in minified code.
 stack_trace_test: RuntimeError, OK # Stack trace not preserved in minified code.
 
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index 2902b0f..f24119b 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -1205,7 +1205,6 @@
 super_setter_test: StaticWarning # Issue 28823
 switch_case_test/none: CompileTimeError
 type_inference_accessor_ref_test/06: MissingCompileTimeError
-type_inference_circularity_test: MissingCompileTimeError
 type_promotion_functions_test/01: Pass
 type_promotion_functions_test/05: Pass
 type_promotion_functions_test/06: Pass
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 22eab3f..d7f5dbe 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -263,9 +263,6 @@
 implicit_downcast_during_while_statement_test: RuntimeError
 inferrer_synthesized_constructor_test: RuntimeError
 malformed2_test/00: MissingCompileTimeError
-mixin_mixin2_test: RuntimeError
-mixin_mixin3_test: RuntimeError
-mixin_mixin_type_arguments_test: RuntimeError
 mixin_type_parameters_super_test: RuntimeError
 type_parameter_test/05: MissingCompileTimeError
 typevariable_substitution2_test/02: RuntimeError
@@ -637,8 +634,6 @@
 mixin_illegal_superclass_test/29: MissingCompileTimeError
 mixin_illegal_superclass_test/30: MissingCompileTimeError
 mixin_issue10216_2_test: RuntimeError
-mixin_mixin2_test: RuntimeError
-mixin_mixin3_test: RuntimeError
 mixin_mixin4_test: RuntimeError
 mixin_mixin5_test: RuntimeError
 mixin_mixin6_test: RuntimeError
@@ -646,7 +641,6 @@
 mixin_mixin_bound2_test: RuntimeError
 mixin_mixin_bound_test: RuntimeError
 mixin_mixin_test: RuntimeError
-mixin_mixin_type_arguments_test: RuntimeError
 mixin_of_mixin_test/none: CompileTimeError
 mixin_super_2_test/none: CompileTimeError
 mixin_super_constructor_named_test/01: MissingCompileTimeError
@@ -1229,8 +1223,6 @@
 mixin_illegal_superclass_test/29: MissingCompileTimeError
 mixin_illegal_superclass_test/30: MissingCompileTimeError
 mixin_issue10216_2_test: RuntimeError
-mixin_mixin2_test: RuntimeError
-mixin_mixin3_test: RuntimeError
 mixin_mixin4_test: RuntimeError
 mixin_mixin5_test: RuntimeError
 mixin_mixin6_test: RuntimeError
@@ -1238,7 +1230,6 @@
 mixin_mixin_bound2_test: RuntimeError
 mixin_mixin_bound_test: RuntimeError
 mixin_mixin_test: RuntimeError
-mixin_mixin_type_arguments_test: RuntimeError
 mixin_of_mixin_test/none: CompileTimeError
 mixin_super_2_test/none: CompileTimeError
 mixin_super_constructor_named_test/01: MissingCompileTimeError
@@ -1798,9 +1789,6 @@
 mixin_invalid_bound_test/08: MissingCompileTimeError
 mixin_invalid_bound_test/09: MissingCompileTimeError
 mixin_invalid_bound_test/10: MissingCompileTimeError
-mixin_mixin2_test: RuntimeError
-mixin_mixin3_test: RuntimeError
-mixin_mixin_type_arguments_test: RuntimeError
 mixin_of_mixin_test/none: CompileTimeError
 mixin_regress_13688_test: Crash # Assertion failure: Only 2 of 3 arguments have been read from: [HRef(HForeignCode("# ? Object.keys(#) : []")), literal: NullConstant, literal: NullConstant]
 mixin_super_2_test/none: CompileTimeError
@@ -2567,7 +2555,6 @@
 mixin_invalid_bound_test/08: MissingCompileTimeError
 mixin_invalid_bound_test/09: MissingCompileTimeError
 mixin_invalid_bound_test/10: MissingCompileTimeError
-mixin_mixin_type_arguments_test: RuntimeError
 mixin_of_mixin_test/none: CompileTimeError
 mixin_super_2_test/none: CompileTimeError
 mixin_super_bound_test/01: MissingCompileTimeError
@@ -3437,9 +3424,6 @@
 mixin_invalid_bound_test/08: MissingCompileTimeError
 mixin_invalid_bound_test/09: MissingCompileTimeError
 mixin_invalid_bound_test/10: MissingCompileTimeError
-mixin_mixin2_test: RuntimeError # Issue 13109.
-mixin_mixin3_test: RuntimeError # Issue 13109.
-mixin_mixin_type_arguments_test: RuntimeError # Issue 29587
 mixin_of_mixin_test/none: CompileTimeError
 mixin_super_2_test/none: CompileTimeError
 mixin_super_bound2_test: CompileTimeError # Issue 23773
@@ -3873,6 +3857,7 @@
 mixin_mixin6_test: RuntimeError # Issue 31054
 mixin_mixin_bound2_test: RuntimeError # Issue 31054
 mixin_mixin_bound_test: RuntimeError # Issue 31054
+mixin_mixin_type_arguments_test: RuntimeError # Issue 31054
 
 [ $compiler == dart2js && !$strong ]
 dynamic_test: RuntimeError
diff --git a/tests/language_2/vm/await_synchronous_future_test.dart b/tests/language_2/vm/await_synchronous_future_test.dart
new file mode 100644
index 0000000..9ccf5dc
--- /dev/null
+++ b/tests/language_2/vm/await_synchronous_future_test.dart
@@ -0,0 +1,48 @@
+// 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.
+
+// Test that async/await syntax works for synchronously completed futures.
+// Such futures are used by Flutter (see http://dartbug.com/32098).
+
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+class SynchronousFuture<T> implements Future<T> {
+  final T v;
+
+  SynchronousFuture(this.v);
+
+  Future<E> then<E>(FutureOr<E> f(T v), {Function onError}) {
+    final u = f(v);
+    return u is Future<dynamic>
+        ? (u as Future<dynamic>).then((v) => v as E)
+        : new SynchronousFuture<E>(u);
+  }
+
+  Stream<T> asStream() => throw 'unimplemented';
+  Future<T> catchError(Function onError, {bool test(dynamic error)}) =>
+      throw 'unimplemented';
+  Future<T> timeout(Duration timeLimit, {dynamic onTimeout()}) =>
+      throw 'unimplemented';
+  Future<T> whenComplete(dynamic action()) => throw 'unimplemented';
+}
+
+void main() {
+  var stage = 0;
+  asyncTest(() async {
+    int v;
+    Expect.equals(0, stage++);
+    v = await new SynchronousFuture<int>(stage);
+    Expect.equals(1, v);
+    Expect.equals(1, stage++);
+    v = await new SynchronousFuture<int>(stage);
+    Expect.equals(2, v);
+    Expect.equals(2, stage++);
+    v = await new SynchronousFuture<int>(stage);
+    Expect.equals(3, v);
+    Expect.equals(3, stage++);
+  });
+}
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index 21b3a73..87a6273 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -68,6 +68,7 @@
 typed_data/int32x4_arithmetic_test/int64: RuntimeError # Issue 1533
 typed_data/int64_list_load_store_test: RuntimeError # Issue 10275
 typed_data/typed_data_hierarchy_int64_test: RuntimeError # Issue 10275
+typed_data/unmodifiable_typed_data_test: RuntimeError # Issue 10275
 
 [ $compiler != dart2js ]
 async/dart2js_uncaught_error_test: Skip # JS-integration only test
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index dd36b16..c90982c 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -130,4 +130,4 @@
 typed_data/int32x4_arithmetic_test/int64: RuntimeError # Issue 29922
 typed_data/int64_list_load_store_test: RuntimeError # Issue 29922
 typed_data/typed_data_hierarchy_int64_test: RuntimeError # Issue 29922
-
+typed_data/unmodifiable_typed_data_test: RuntimeError # Issue 10275
diff --git a/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart b/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
new file mode 100644
index 0000000..70708c5
--- /dev/null
+++ b/tests/lib_2/typed_data/unmodifiable_typed_data_test.dart
@@ -0,0 +1,165 @@
+// 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.
+
+import 'dart:typed_data';
+import 'package:expect/expect.dart';
+
+List<int> intList = <int>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+
+checkReadable(List<int> list) {
+  for (int i = 0; i < intList.length; i++) {
+    Expect.equals(list[i], intList[i]);
+  }
+}
+
+checkUnmodifiable(List<int> list) {
+  var zero = 0;
+  var one = 1;
+  var two = 2;
+  Expect.throwsUnsupportedError(() => list.add(zero));
+  Expect.throwsUnsupportedError(() => list.addAll([one, two]));
+  Expect.throwsUnsupportedError(() => list.clear());
+  Expect.throwsUnsupportedError(() => list.insert(0, zero));
+  Expect.throwsUnsupportedError(() => list.insertAll(0, [one, two]));
+  Expect.throwsUnsupportedError(() => list.remove(one));
+  Expect.throwsUnsupportedError(() => list.removeAt(0));
+  Expect.throwsUnsupportedError(() => list.removeLast());
+  Expect.throwsUnsupportedError(() => list.removeRange(0, 1));
+  Expect.throwsUnsupportedError(() => list.removeWhere((x) => true));
+  Expect.throwsUnsupportedError(() => list.replaceRange(0, 1, []));
+  Expect.throwsUnsupportedError(() => list.retainWhere((x) => false));
+  Expect.throwsUnsupportedError(() => list[0] = zero);
+  Expect.throwsUnsupportedError(() => list.setRange(0, 1, [one]));
+  Expect.throwsUnsupportedError(() => list.setAll(0, [one]));
+}
+
+int8ListTest() {
+  Int8List i8l = new Int8List.fromList(intList);
+  UnmodifiableInt8ListView list = new UnmodifiableInt8ListView(i8l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+uint8ListTest() {
+  Uint8List u8l = new Uint8List.fromList(intList);
+  UnmodifiableUint8ListView list = new UnmodifiableUint8ListView(u8l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+int16ListTest() {
+  Int16List i16l = new Int16List.fromList(intList);
+  UnmodifiableInt16ListView list = new UnmodifiableInt16ListView(i16l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+uint16ListTest() {
+  Uint16List u16l = new Uint16List.fromList(intList);
+  UnmodifiableUint16ListView list = new UnmodifiableUint16ListView(u16l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+int32ListTest() {
+  Int32List i32l = new Int32List.fromList(intList);
+  UnmodifiableInt32ListView list = new UnmodifiableInt32ListView(i32l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+uint32ListTest() {
+  Uint32List u32l = new Uint32List.fromList(intList);
+  UnmodifiableUint32ListView list = new UnmodifiableUint32ListView(u32l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+int64ListTest() {
+  Int64List i64l = new Int64List.fromList(intList);
+  UnmodifiableInt64ListView list = new UnmodifiableInt64ListView(i64l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+uint64ListTest() {
+  Uint64List u64l = new Uint64List.fromList(intList);
+  UnmodifiableUint64ListView list = new UnmodifiableUint64ListView(u64l);
+  checkReadable(list);
+  checkUnmodifiable(list);
+}
+
+List<double> doubleList = <double>[1.0, 2.0, 3.0, 4.0, 5.0];
+
+checkDoubleReadable(List<double> list) {
+  for (int i = 0; i < doubleList.length; i++) {
+    Expect.equals(list[i], doubleList[i]);
+  }
+}
+
+checkDoubleUnmodifiable(List<double> list) {
+  var zero = 0.0;
+  var one = 1.0;
+  var two = 2.0;
+  Expect.throwsUnsupportedError(() => list.add(zero));
+  Expect.throwsUnsupportedError(() => list.addAll([one, two]));
+  Expect.throwsUnsupportedError(() => list.clear());
+  Expect.throwsUnsupportedError(() => list.insert(0, zero));
+  Expect.throwsUnsupportedError(() => list.insertAll(0, [one, two]));
+  Expect.throwsUnsupportedError(() => list.remove(one));
+  Expect.throwsUnsupportedError(() => list.removeAt(0));
+  Expect.throwsUnsupportedError(() => list.removeLast());
+  Expect.throwsUnsupportedError(() => list.removeRange(0, 1));
+  Expect.throwsUnsupportedError(() => list.removeWhere((x) => true));
+  Expect.throwsUnsupportedError(() => list.replaceRange(0, 1, []));
+  Expect.throwsUnsupportedError(() => list.retainWhere((x) => false));
+  Expect.throwsUnsupportedError(() => list[0] = zero);
+  Expect.throwsUnsupportedError(() => list.setRange(0, 1, [one]));
+  Expect.throwsUnsupportedError(() => list.setAll(0, [one]));
+}
+
+float32ListTest() {
+  Float32List f32l = new Float32List.fromList(doubleList);
+  UnmodifiableFloat32ListView list = new UnmodifiableFloat32ListView(f32l);
+  checkDoubleReadable(list);
+  checkDoubleUnmodifiable(list);
+}
+
+float64ListTest() {
+  Float64List f64l = new Float64List.fromList(doubleList);
+  UnmodifiableFloat64ListView list = new UnmodifiableFloat64ListView(f64l);
+  checkDoubleReadable(list);
+  checkDoubleUnmodifiable(list);
+}
+
+byteDataTest() {
+  ByteBuffer buffer = new Uint8List.fromList(intList).buffer;
+  ByteData bd = new ByteData.view(buffer);
+  UnmodifiableByteDataView ubdv = new UnmodifiableByteDataView(bd);
+
+  Expect.throwsUnsupportedError(() => ubdv.setInt8(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setUint8(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setInt16(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setUint16(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setInt32(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setUint32(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setInt64(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setUint64(0, 0));
+  Expect.throwsUnsupportedError(() => ubdv.setFloat32(0, 0.0));
+  Expect.throwsUnsupportedError(() => ubdv.setFloat64(0, 0.0));
+}
+
+main() {
+  int8ListTest();
+  uint8ListTest();
+  int16ListTest();
+  uint16ListTest();
+  int32ListTest();
+  uint32ListTest();
+  int64ListTest();
+  uint64ListTest();
+  float32ListTest();
+  float64ListTest();
+  byteDataTest();
+}
diff --git a/tools/VERSION b/tools/VERSION
index 1145d30..f6a0fd2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 0
 PATCH 0
-PRERELEASE 23
+PRERELEASE 24
 PRERELEASE_PATCH 0
diff --git a/tools/testing/dart/command.dart b/tools/testing/dart/command.dart
index 0a25554..b2680ca 100644
--- a/tools/testing/dart/command.dart
+++ b/tools/testing/dart/command.dart
@@ -115,6 +115,24 @@
     return new MakeSymlinkCommand._(link, target);
   }
 
+  static Command fasta(
+      Uri compilerLocation,
+      Uri outputFile,
+      List<Uri> bootstrapDependencies,
+      Uri executable,
+      List<String> arguments,
+      Map<String, String> environment,
+      Uri workingDirectory) {
+    return new FastaCompilationCommand._(
+        compilerLocation,
+        outputFile,
+        bootstrapDependencies,
+        executable,
+        arguments,
+        environment,
+        workingDirectory);
+  }
+
   /// A descriptive name for this command.
   final String displayName;
 
@@ -282,6 +300,73 @@
       deepJsonCompare(_bootstrapDependencies, other._bootstrapDependencies);
 }
 
+class FastaCompilationCommand extends CompilationCommand {
+  final Uri _compilerLocation;
+
+  FastaCompilationCommand._(
+      this._compilerLocation,
+      Uri outputFile,
+      List<Uri> bootstrapDependencies,
+      Uri executable,
+      List<String> arguments,
+      Map<String, String> environmentOverrides,
+      Uri workingDirectory)
+      : super._("fasta", outputFile.toFilePath(), true, bootstrapDependencies,
+            executable.toFilePath(), arguments, environmentOverrides,
+            workingDirectory: workingDirectory?.toFilePath());
+
+  @override
+  List<String> get batchArguments {
+    return <String>[
+      _compilerLocation.resolve("batch.dart").toFilePath(),
+    ];
+  }
+
+  @override
+  String get reproductionCommand {
+    String relativizeAndEscape(String argument) {
+      if (workingDirectory != null) {
+        argument = argument.replaceAll(
+            workingDirectory, new Uri.directory(".").toFilePath());
+      }
+      return escapeCommandLineArgument(argument);
+    }
+
+    StringBuffer buffer = new StringBuffer();
+    if (workingDirectory != null && !io.Platform.isWindows) {
+      buffer.write("(cd ");
+      buffer.write(escapeCommandLineArgument(workingDirectory));
+      buffer.write(" ; ");
+    }
+    environmentOverrides?.forEach((key, value) {
+      if (io.Platform.isWindows) {
+        buffer.write("set ");
+      }
+      buffer.write(key);
+      buffer.write("=");
+      buffer.write(relativizeAndEscape(value));
+      if (io.Platform.isWindows) {
+        buffer.write(" &");
+      }
+      buffer.write(" ");
+    });
+    buffer.writeAll(
+        (<String>[executable]
+              ..add(_compilerLocation.toFilePath())
+              ..addAll(arguments))
+            .map(relativizeAndEscape),
+        " ");
+    if (workingDirectory != null) {
+      if (io.Platform.isWindows) {
+        buffer.write(" (working directory: $workingDirectory)");
+      } else {
+        buffer.write(" )");
+      }
+    }
+    return "$buffer";
+  }
+}
+
 class VMKernelCompilationCommand extends CompilationCommand {
   VMKernelCompilationCommand._(
       String outputFile,
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 8cb66ae..ac20f0b 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -85,8 +85,10 @@
       case Compiler.specParser:
         return new SpecParserCompilerConfiguration(configuration);
 
+      case Compiler.fasta:
+        return new FastaCompilerConfiguration(configuration);
+
       case Compiler.none:
-      case Compiler.fasta: // TODO(ahe): Implement a real fasta compiler.
         return new NoneCompilerConfiguration(configuration);
     }
 
@@ -161,7 +163,6 @@
       List<String> sharedOptions,
       List<String> originalArguments,
       CommandArtifact artifact) {
-    var buildDir = _configuration.buildDirectory;
     var args = <String>[];
     if (useDfe) {
       // DFE+strong configuration is a Dart 2.0 configuration which uses
@@ -1080,3 +1081,117 @@
         genKernel, args, environmentOverrides);
   }
 }
+
+class FastaCompilerConfiguration extends CompilerConfiguration {
+  static const String mimeType = "application/x.dill";
+
+  final Uri _compilerLocation;
+
+  final Uri _plaformDill;
+
+  final Uri _vmExecutable;
+
+  final bool _isLegacy;
+
+  FastaCompilerConfiguration(Configuration configuration)
+      : this._(
+            Uri.base.resolve("pkg/front_end/tool/_fasta/compile.dart"),
+            Uri.base
+                .resolveUri(new Uri.directory(configuration.buildDirectory)),
+            !configuration.isStrong,
+            configuration.useSdk,
+            configuration);
+
+  FastaCompilerConfiguration._(this._compilerLocation, Uri buildDirectory,
+      this._isLegacy, bool useSdk, Configuration configuration)
+      : _plaformDill = (useSdk
+                ? buildDirectory.resolve("dart-sdk/lib/_internal/")
+                : buildDirectory)
+            .resolve(
+                _isLegacy ? "vm_platform.dill" : "vm_platform_strong.dill"),
+        _vmExecutable = useSdk
+            ? buildDirectory.resolve("dart-sdk/bin/dart")
+            : buildDirectory.resolve("dart"),
+        super._subclass(configuration);
+
+  @override
+  bool get useDfe => true;
+
+  @override
+  bool get runRuntimeDespiteMissingCompileTimeError => true;
+
+  @override
+  int get timeoutMultiplier => 1;
+
+  @override
+  bool get hasCompiler => true;
+
+  @override
+  List<Uri> bootstrapDependencies() => <Uri>[_plaformDill];
+
+  @override
+  Command createCommand(String inputFile, String outputFile,
+      List<String> sharedOptions, Map<String, String> environment) {
+    throw "not implemented yet";
+  }
+
+  @override
+  CommandArtifact computeCompilationArtifact(String tempDir,
+      List<String> arguments, Map<String, String> environmentOverrides) {
+    Uri output =
+        Uri.base.resolveUri(new Uri.directory(tempDir)).resolve("out.dill");
+    String outputFileName = output.toFilePath();
+    String vmPath = _vmExecutable.toFilePath();
+    if (Platform.isWindows) {
+      vmPath += ".exe";
+    }
+    List<String> compilerArguments = <String>[
+      "-o",
+      outputFileName,
+      "--platform",
+      _plaformDill.toFilePath(),
+    ]..addAll(arguments);
+
+    return new CommandArtifact(
+      [
+        Command.fasta(
+          _compilerLocation,
+          output,
+          bootstrapDependencies(),
+          _vmExecutable,
+          compilerArguments,
+          environmentOverrides,
+          Uri.base,
+        )
+      ],
+      outputFileName,
+      mimeType,
+    );
+  }
+
+  @override
+  List<String> computeCompilerArguments(
+      List<String> vmOptions,
+      List<String> sharedOptions,
+      List<String> dart2jsOptions,
+      List<String> args) {
+    List<String> arguments = <String>[];
+    for (String argument in args) {
+      if (argument != "--ignore-unrecognized-flags") {
+        arguments.add(argument);
+      }
+    }
+    return arguments;
+  }
+
+  @override
+  List<String> computeRuntimeArguments(
+      RuntimeConfiguration runtimeConfiguration,
+      TestInformation info,
+      List<String> vmOptions,
+      List<String> sharedOptions,
+      List<String> originalArguments,
+      CommandArtifact artifact) {
+    return <String>[];
+  }
+}
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 2cb2950..5c743b3 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -572,6 +572,10 @@
 }
 
 class BatchRunnerProcess {
+  /// When true, the command line is passed to the test runner as a
+  /// JSON-encoded list of strings.
+  final bool _jsonCommandLine;
+
   Completer<CommandOutput> _completer;
   ProcessCommand _command;
   List<String> _arguments;
@@ -593,6 +597,8 @@
   Timer _timer;
   int _testCount = 0;
 
+  BatchRunnerProcess(this._jsonCommandLine);
+
   Future<CommandOutput> runCommand(String runnerType, ProcessCommand command,
       int timeout, List<String> arguments) {
     assert(_completer == null);
@@ -664,7 +670,11 @@
   }
 
   String _createArgumentsLine(List<String> arguments, int timeout) {
-    return arguments.join(' ') + '\n';
+    if (_jsonCommandLine) {
+      return "${JSON.encode(arguments)}\n";
+    } else {
+      return arguments.join(' ') + '\n';
+    }
   }
 
   void _reportResult() {
@@ -1161,7 +1171,8 @@
           .runCommand(command.displayName, command, timeout, command.arguments);
     } else if (command is CompilationCommand &&
         (command.displayName == 'dartdevc' ||
-            command.displayName == 'dartdevk') &&
+            command.displayName == 'dartdevk' ||
+            command.displayName == 'fasta') &&
         globalConfiguration.batch) {
       return _getBatchRunner(command.displayName)
           .runCommand(command.displayName, command, timeout, command.arguments);
@@ -1269,7 +1280,7 @@
     if (runners == null) {
       runners = new List<BatchRunnerProcess>(maxProcesses);
       for (int i = 0; i < maxProcesses; i++) {
-        runners[i] = new BatchRunnerProcess();
+        runners[i] = new BatchRunnerProcess(identifier == "fasta");
       }
       _batchProcesses[identifier] = runners;
     }