Version 2.1.0-dev.3.0

Merge commit '8b5a2b0' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 02e5dcc..758e334 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+## 2.1.0-dev.3.0
+
+### Core library changes
+
+* `dart:async`
+  * Update `Stream.fromIterable` to send a done event after the error when the
+    iterator's `moveNext` throws, and handle if the `current` getter throws.
+    Issue [33431](http://dartbug.com/33431).
+
 ## 2.1.0-dev.2.0
 
 ### Tool Changes
diff --git a/DEPS b/DEPS
index 32c23b4..8f5c4c4 100644
--- a/DEPS
+++ b/DEPS
@@ -95,7 +95,7 @@
   "intl_tag": "0.15.6",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.59",
+  "linter_tag": "0.1.60",
   "logging_tag": "0.11.3+2",
   "markdown_tag": "2.0.2",
   "matcher_tag": "0.12.3",
@@ -157,7 +157,7 @@
       "packages": [
           {
               "package": "dart/dart-sdk/${{platform}}",
-              "version": "version:2.0.0-dev.69.5",
+              "version": "version:2.1.0-dev.2.0",
           },
       ],
       "dep_type": "cipd",
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 8e19bd2..051d913 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -25,6 +25,8 @@
 %   constructor invocation.
 % - Specify that type arguments passed in a redirecting factory constructor
 %   declaration must be taken into account during static checks.
+% - Disallow any expression statement starting with `{`, not just
+%   those that are map literals.
 %
 % 2.0
 % - Don't allow functions as assert test values.
@@ -7826,11 +7828,8 @@
 \LMLabel{expressionStatements}
 
 \LMHash{}
-An {\em expression statement} consists of an expression other than a non-constant map literal (\ref{maps}) that has no explicit type arguments.
-
-\rationale{
-The restriction on maps is designed to resolve an ambiguity in the grammar, when a statement begins with \{.
-}
+An {\em expression statement} consists of an expression that does not
+begin with a \{ character.
 
 \begin{grammar}
 {\bf expressionStatement:}expression? `{\escapegrammar ;}'
@@ -7838,11 +7837,24 @@
 \end{grammar}
 
 \LMHash{}
-Execution of an expression statement \code{$e$;} proceeds by evaluating $e$.
+The expression of an expression statement is not allowed to begin with a \{.
+\commentary{
+This means that if some source text could otherwise be parsed as an expression
+followed by a \;, then this grammar production does not apply
+when the expression starts with a \{.
+}
+\rationale{
+The restriction resolves an ambiguity while parsing where a
+\{ can start either a block (\ref{blocks}) or a map literal (\ref{maps}).
+By disallowing the latter from starting an expression statement,
+the parser does not need to look further ahead
+before deciding that it is parsing a block statement.
+}
 
 \LMHash{}
-It is a compile-time error if a non-constant map literal that has no explicit type arguments appears in a place where a statement is expected.
-
+Execution of an expression statement \code{$e$;} proceeds by evaluating $e$.
+If the expression evaluates to a value, then the value is ignored
+and the execution completes normally.
 
 \subsection{Local Variable Declaration}
 \LMLabel{localVariableDeclaration}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index 7a560c3..654c128 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -62,7 +62,16 @@
       }
     }
     if (parent is Annotation) {
-      return parent.constructorName ?? parent.name;
+      SimpleIdentifier name = parent.constructorName;
+      if (name == null) {
+        Identifier parentName = parent.name;
+        if (parentName is SimpleIdentifier) {
+          return parentName;
+        } else if (parentName is PrefixedIdentifier) {
+          return parentName.identifier;
+        }
+      }
+      return name;
     }
   }
   return null;
diff --git a/pkg/analysis_server/test/integration/edit/get_postfix_completion_test.dart b/pkg/analysis_server/test/integration/edit/get_postfix_completion_test.dart
index 8e34a3b..d7c5fd3 100644
--- a/pkg/analysis_server/test/integration/edit/get_postfix_completion_test.dart
+++ b/pkg/analysis_server/test/integration/edit/get_postfix_completion_test.dart
@@ -18,6 +18,7 @@
 
 @reflectiveTest
 class GetPostfixCompletionTest extends AbstractAnalysisServerIntegrationTest {
+  @TestTimeout(const Timeout.factor(2))
   test_postfix_completion() async {
     String pathname = sourcePath('test.dart');
     String text = r'''
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 8271e2b..abb74ac 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -152,6 +152,21 @@
         namedArgumentsWithTypes: {'one': 'int', 'two': 'String'});
   }
 
+  test_Annotation_importedConstructor_prefixed() async {
+    addSource('/libA.dart', '''
+class A {
+  const A({int value});
+}
+''');
+    addTestSource('''
+import "${convertPathForImport("/libA.dart")}" as p;
+@p.A(^)
+main() {}
+''');
+    await computeSuggestions();
+    assertSuggestArgumentsAndTypes(namedArgumentsWithTypes: {'value': 'int'});
+  }
+
   test_Annotation_local_constructor_named_param() async {
     addTestSource('''
 class A { const A({int one, String two: 'defaultValue'}); }
@@ -1046,14 +1061,4 @@
 class ArgListContributorTest_UseCFE extends ArgListContributorTest {
   @override
   bool get useCFE => true;
-
-  @failingTest
-  @override
-  test_ArgumentList_local_constructor_named_param_4() =>
-      super.test_ArgumentList_local_constructor_named_param_4();
-
-  @failingTest
-  @override
-  test_ArgumentList_local_constructor_named_param_5() =>
-      super.test_ArgumentList_local_constructor_named_param_5();
 }
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 18e4340..84c538a 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -448,6 +448,7 @@
   /**
    * An empty list of AST nodes.
    */
+  @deprecated
   static const List<AstNode> EMPTY_LIST = const <AstNode>[];
 
   /**
@@ -2597,6 +2598,7 @@
   /**
    * An empty list of expressions.
    */
+  @deprecated
   static const List<Expression> EMPTY_LIST = const <Expression>[];
 
   /**
@@ -5206,7 +5208,7 @@
 
   /**
    * Return the on clause for the mixin, or `null` if the mixin does not have
-   * any super-class constraints.
+   * any superclass constraints.
    */
   OnClause get onClause;
 
@@ -5608,7 +5610,7 @@
   Token get onKeyword;
 
   /**
-   * Return the list of the classes are super-class constraints for the mixin.
+   * Return the list of the classes are superclass constraints for the mixin.
    */
   NodeList<TypeName> get superclassConstraints;
 }
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 34ee3c9..7e2ca4c 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -48,7 +48,9 @@
 import 'package:analyzer/src/task/dart.dart';
 
 /**
- * An element that represents a class.
+ * An element that represents a class or a mixin. The class can be defined by
+ * either a class declaration (with a class body), a mixin application (without
+ * a class body), a mixin declaration, or an enum declaration.
  *
  * Clients may not extend, implement or mix-in this class.
  */
@@ -57,6 +59,7 @@
   /**
    * An empty list of class elements.
    */
+  @deprecated
   static const List<ClassElement> EMPTY_LIST = const <ClassElement>[];
 
   /**
@@ -67,12 +70,15 @@
 
   /**
    * Return a list containing all the supertypes defined for this class and its
-   * supertypes. This includes superclasses, mixins and interfaces.
+   * supertypes. This includes superclasses, mixins, interfaces and superclass
+   * constraints.
    */
   List<InterfaceType> get allSupertypes;
 
   /**
    * Return a list containing all of the constructors declared in this class.
+   * The list will be empty if there are no constructors defined for this class,
+   * as is the case when this element represents an enum or a mixin.
    */
   List<ConstructorElement> get constructors;
 
@@ -88,8 +94,10 @@
   bool get hasNonFinalField;
 
   /**
-   * Return `true` if this class has reference to super (so, for example, cannot
-   * be used as a mixin).
+   * Return `true` if this class has at least one reference to `super` (and
+   * hence cannot be used as a mixin), or `false` if this element represents a
+   * mixin, even if the mixin has a reference to `super`, because it is allowed
+   * to be used as a mixin.
    */
   bool get hasReferenceToSuper;
 
@@ -112,8 +120,9 @@
 
   /**
    * Return `true` if this class is abstract. A class is abstract if it has an
-   * explicit `abstract` modifier. Note, that this definition of <i>abstract</i>
-   * is different from <i>has unimplemented members</i>.
+   * explicit `abstract` modifier or if it is implicitly abstract, such as a
+   * class defined by a mixin declaration. Note, that this definition of
+   * <i>abstract</i> is different from <i>has unimplemented members</i>.
    */
   bool get isAbstract;
 
@@ -123,6 +132,11 @@
   bool get isEnum;
 
   /**
+   * Return `true` if this class is defined by a mixin declaration.
+   */
+  bool get isMixin;
+
+  /**
    * Return `true` if this class is a mixin application.  A class is a mixin
    * application if it was declared using the syntax "class A = B with C;".
    */
@@ -141,7 +155,9 @@
 
   /**
    * Return `true` if this class can validly be used as a mixin when defining
-   * another class. The behavior of this method is defined by the Dart Language
+   * another class. For classes defined by a mixin declaration, the result is
+   * always `true`. For classes defined by a class declaration or a mixin
+   * application, the behavior of this method is defined by the Dart Language
    * Specification in section 9:
    * <blockquote>
    * It is a compile-time error if a declared or derived mixin refers to super.
@@ -170,8 +186,24 @@
   List<InterfaceType> get mixins;
 
   /**
-   * Return the superclass of this class, or `null` if the class represents the
-   * class 'Object'. All other classes will have a non-`null` superclass. If the
+   * Return a list containing all of the superclass constraints defined for this
+   * class. The list will be empty if this class does not represent a mixin
+   * declaration. If this class _does_ represent a mixin declaration but the
+   * declaration does not have an on clause, then the list will contain the type
+   * for the class `Object`.
+   *
+   * <b>Note:</b> Because the element model represents the state of the code, it
+   * is possible for it to be semantically invalid. In particular, it is not
+   * safe to assume that the inheritance structure of a class does not contain a
+   * cycle. Clients that traverse the inheritance structure must explicitly
+   * guard against infinite loops.
+   */
+  List<InterfaceType> get superclassConstraints;
+
+  /**
+   * Return the superclass of this class, or `null` if either the class
+   * represents the class 'Object' or if the class represents a mixin
+   * declaration. All other classes will have a non-`null` superclass. If the
    * superclass was not explicitly declared then the implicit superclass
    * 'Object' will be returned.
    *
@@ -187,11 +219,12 @@
   InterfaceType get type;
 
   /**
-   * Return the unnamed constructor declared in this class, or `null` if this
-   * class does not declare an unnamed constructor but does declare named
-   * constructors. The returned constructor will be synthetic if this class does
-   * not declare any constructors, in which case it will represent the default
-   * constructor for the class.
+   * Return the unnamed constructor declared in this class, or `null` if either
+   * this class does not declare an unnamed constructor but does declare named
+   * constructors or if this class represents a mixin declaration. The returned
+   * constructor will be synthetic if this class does not declare any
+   * constructors, in which case it will represent the default constructor for
+   * the class.
    */
   ConstructorElement get unnamedConstructor;
 
@@ -415,6 +448,7 @@
   /**
    * An empty list of compilation unit elements.
    */
+  @deprecated
   static const List<CompilationUnitElement> EMPTY_LIST =
       const <CompilationUnitElement>[];
 
@@ -497,6 +531,7 @@
   /**
    * An empty list of constructor elements.
    */
+  @deprecated
   static const List<ConstructorElement> EMPTY_LIST =
       const <ConstructorElement>[];
 
@@ -650,6 +685,11 @@
   bool get hasRequired;
 
   /**
+   * Return `true` if this element has an annotation of the form '@sealed'.
+   */
+  bool get hasSealed;
+
+  /**
    * Return `true` if this element has an annotation of the form
    * `@visibleForTemplate`.
    */
@@ -867,6 +907,7 @@
   /**
    * An empty list of annotations.
    */
+  @deprecated
   static const List<ElementAnnotation> EMPTY_LIST = const <ElementAnnotation>[];
 
   /**
@@ -955,6 +996,12 @@
   bool get isRequired;
 
   /**
+   * Return `true` if this annotation marks the associated class as being
+   * sealed.
+   */
+  bool get isSealed;
+
+  /**
    * Return `true` if this annotation marks the associated member as being
    * visible for template files.
    */
@@ -1199,6 +1246,7 @@
   /**
    * An empty list of executable elements.
    */
+  @deprecated
   static const List<ExecutableElement> EMPTY_LIST = const <ExecutableElement>[];
 
   /**
@@ -1264,6 +1312,7 @@
   /**
    * An empty list of export elements.
    */
+  @deprecated
   static const List<ExportElement> EMPTY_LIST = const <ExportElement>[];
 
   /**
@@ -1289,6 +1338,7 @@
   /**
    * An empty list of field elements.
    */
+  @deprecated
   static const List<FieldElement> EMPTY_LIST = const <FieldElement>[];
 
   /**
@@ -1329,6 +1379,7 @@
   /**
    * An empty list of function elements.
    */
+  @deprecated
   static const List<FunctionElement> EMPTY_LIST = const <FunctionElement>[];
 
   /**
@@ -1373,6 +1424,7 @@
   /**
    * An empty array of type alias elements.
    */
+  @deprecated
   static List<FunctionTypeAliasElement> EMPTY_LIST =
       new List<FunctionTypeAliasElement>(0);
 
@@ -1463,6 +1515,7 @@
   /**
    * An empty list of import elements.
    */
+  @deprecated
   static const List<ImportElement> EMPTY_LIST = const <ImportElement>[];
 
   /**
@@ -1510,6 +1563,7 @@
   /**
    * An empty list of label elements.
    */
+  @deprecated
   static const List<LabelElement> EMPTY_LIST = const <LabelElement>[];
 
   @override
@@ -1525,6 +1579,7 @@
   /**
    * An empty list of library elements.
    */
+  @deprecated
   static const List<LibraryElement> EMPTY_LIST = const <LibraryElement>[];
 
   /**
@@ -1694,6 +1749,7 @@
   /**
    * An empty list of field elements.
    */
+  @deprecated
   static const List<LocalVariableElement> EMPTY_LIST =
       const <LocalVariableElement>[];
 }
@@ -1707,6 +1763,7 @@
   /**
    * An empty list of method elements.
    */
+  @deprecated
   static const List<MethodElement> EMPTY_LIST = const <MethodElement>[];
 
   @override
@@ -1768,6 +1825,7 @@
   /**
    * An empty list of namespace combinators.
    */
+  @deprecated
   static const List<NamespaceCombinator> EMPTY_LIST =
       const <NamespaceCombinator>[];
 }
@@ -1782,6 +1840,7 @@
   /**
    * An empty list of parameter elements.
    */
+  @deprecated
   static const List<ParameterElement> EMPTY_LIST = const <ParameterElement>[];
 
   /**
@@ -1874,6 +1933,7 @@
   /**
    * An empty list of prefix elements.
    */
+  @deprecated
   static const List<PrefixElement> EMPTY_LIST = const <PrefixElement>[];
 
   @override
@@ -1909,6 +1969,7 @@
   /**
    * An empty list of property accessor elements.
    */
+  @deprecated
   static const List<PropertyAccessorElement> EMPTY_LIST =
       const <PropertyAccessorElement>[];
 
@@ -1967,6 +2028,7 @@
   /**
    * An empty list of elements.
    */
+  @deprecated
   static const List<PropertyInducingElement> EMPTY_LIST =
       const <PropertyInducingElement>[];
 
@@ -2030,6 +2092,7 @@
   /**
    * An empty list of top-level variable elements.
    */
+  @deprecated
   static const List<TopLevelVariableElement> EMPTY_LIST =
       const <TopLevelVariableElement>[];
 
@@ -2058,6 +2121,7 @@
   /**
    * An empty list of type parameter elements.
    */
+  @deprecated
   static const List<TypeParameterElement> EMPTY_LIST =
       const <TypeParameterElement>[];
 
@@ -2136,6 +2200,7 @@
   /**
    * An empty list of variable elements.
    */
+  @deprecated
   static const List<VariableElement> EMPTY_LIST = const <VariableElement>[];
 
   /**
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 7467480..5aa5c3f 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -34,6 +34,7 @@
   /**
    * An empty list of types.
    */
+  @deprecated
   static const List<DartType> EMPTY_LIST = const <DartType>[];
 
   /**
@@ -351,6 +352,7 @@
   /**
    * An empty list of types.
    */
+  @deprecated
   static const List<InterfaceType> EMPTY_LIST = const <InterfaceType>[];
 
   /**
@@ -717,6 +719,7 @@
   /**
    * An empty list of type parameter types.
    */
+  @deprecated
   static const List<TypeParameterType> EMPTY_LIST = const <TypeParameterType>[];
 
   /**
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 4cfcde6..5662d2f 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -305,6 +305,7 @@
   HintCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS,
   HintCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND,
   HintCode.INVALID_REQUIRED_PARAM,
+  HintCode.INVALID_SEALED_ANNOTATION,
   HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
   HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER,
   HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER,
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 40a2d9e..a1834e2 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -949,7 +949,7 @@
   List<TargetedResult> flushToSize() {
     // If still under the cap, done.
     if (currentSize <= maxSize) {
-      return TargetedResult.EMPTY_LIST;
+      return const <TargetedResult>[];
     }
     // Flush results until we are under the cap.
     List<TargetedResult> resultsToFlush = <TargetedResult>[];
@@ -1122,7 +1122,7 @@
    */
   List<Source> getSourcesWithFullName(String path) {
     List<Source> sources = pathToSource[path];
-    return sources ?? Source.EMPTY_LIST;
+    return sources ?? const <Source>[];
   }
 
   /**
@@ -1537,7 +1537,7 @@
 
   @override
   List<TargetedResult> resultStored(TargetedResult newResult, newValue) {
-    return TargetedResult.EMPTY_LIST;
+    return const <TargetedResult>[];
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 9472a8d..c1e0f20 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -334,13 +334,13 @@
   @override
   void set analysisPriorityOrder(List<Source> sources) {
     if (sources == null || sources.isEmpty) {
-      _priorityOrder = Source.EMPTY_LIST;
+      _priorityOrder = const <Source>[];
     } else {
       while (sources.remove(null)) {
         // Nothing else to do.
       }
       if (sources.isEmpty) {
-        _priorityOrder = Source.EMPTY_LIST;
+        _priorityOrder = const <Source>[];
       } else {
         _priorityOrder = sources;
       }
@@ -897,7 +897,7 @@
   @override
   List<Source> getHtmlFilesReferencing(Source source) {
     if (!AnalysisEngine.isDartFileName(source.shortName)) {
-      return Source.EMPTY_LIST;
+      return const <Source>[];
     }
     List<Source> htmlSources = <Source>[];
     List<Source> librarySources = getLibrariesContaining(source);
@@ -911,7 +911,7 @@
       }
     }
     if (htmlSources.isEmpty) {
-      return Source.EMPTY_LIST;
+      return const <Source>[];
     }
     return htmlSources;
   }
@@ -951,7 +951,7 @@
       }
     }
     if (dependentLibraries.isEmpty) {
-      return Source.EMPTY_LIST;
+      return const <Source>[];
     }
     return dependentLibraries;
   }
@@ -962,7 +962,7 @@
     if (entry != null) {
       return entry.getValue(REFERENCED_LIBRARIES);
     }
-    return Source.EMPTY_LIST;
+    return const <Source>[];
   }
 
   @override
@@ -1059,7 +1059,7 @@
         // Don't compare with old contents because the cache has already been
         // updated, and we know at this point that it changed.
         _sourceChanged(source, compareWithOld: false);
-        entry.setValue(CONTENT, newContents, TargetedResult.EMPTY_LIST);
+        entry.setValue(CONTENT, newContents, const <TargetedResult>[]);
       } else {
         entry.modificationTime = _contentCache.getModificationStamp(source);
       }
@@ -1071,7 +1071,7 @@
         newContents = fileContents.data;
         entry.modificationTime = fileContents.modificationTime;
         if (newContents == originalContents) {
-          entry.setValue(CONTENT, newContents, TargetedResult.EMPTY_LIST);
+          entry.setValue(CONTENT, newContents, const <TargetedResult>[]);
           changed = false;
         }
       } catch (e) {}
@@ -1196,7 +1196,7 @@
       //
       CacheEntry entry = getCacheEntry(librarySource);
       setValue(ResultDescriptor result, value) {
-        entry.setValue(result, value, TargetedResult.EMPTY_LIST);
+        entry.setValue(result, value, const <TargetedResult>[]);
       }
 
       setValue(BUILD_DIRECTIVES_ERRORS, AnalysisError.NO_ERRORS);
@@ -1206,11 +1206,11 @@
       // CONSTRUCTORS
       // CONSTRUCTORS_ERRORS
       entry.setState(CONTENT, CacheState.FLUSHED);
-      setValue(EXPORTED_LIBRARIES, Source.EMPTY_LIST);
+      setValue(EXPORTED_LIBRARIES, const <Source>[]);
       // EXPORT_SOURCE_CLOSURE
-      setValue(IMPORTED_LIBRARIES, Source.EMPTY_LIST);
+      setValue(IMPORTED_LIBRARIES, const <Source>[]);
       // IMPORT_SOURCE_CLOSURE
-      setValue(INCLUDED_PARTS, Source.EMPTY_LIST);
+      setValue(INCLUDED_PARTS, const <Source>[]);
       setValue(IS_LAUNCHABLE, false);
       setValue(LIBRARY_ELEMENT, library);
       setValue(LIBRARY_ELEMENT1, library);
@@ -1262,7 +1262,7 @@
     });
 
     CacheEntry entry = getCacheEntry(AnalysisContextTarget.request);
-    entry.setValue(TYPE_PROVIDER, typeProvider, TargetedResult.EMPTY_LIST);
+    entry.setValue(TYPE_PROVIDER, typeProvider, const <TargetedResult>[]);
   }
 
   @override
@@ -1420,7 +1420,7 @@
         CacheEntry entry = _cache.get(source);
         if (entry != null) {
           entry.modificationTime = _contentCache.getModificationStamp(source);
-          entry.setValue(CONTENT, contents, TargetedResult.EMPTY_LIST);
+          entry.setValue(CONTENT, contents, const <TargetedResult>[]);
         }
       }
     } else if (originalContents != null) {
@@ -1501,7 +1501,7 @@
       if (nullIfEmpty) {
         return null;
       }
-      return ChangeNoticeImpl.EMPTY_LIST;
+      return const <ChangeNoticeImpl>[];
     }
     List<ChangeNotice> notices = new List.from(_pendingNotices.values);
     _pendingNotices.clear();
@@ -1529,7 +1529,7 @@
       }
     }
     if (sources.isEmpty) {
-      return Source.EMPTY_LIST;
+      return const <Source>[];
     }
     return sources;
   }
@@ -1801,8 +1801,8 @@
       entry.setState(SOURCE_KIND, CacheState.INVALID);
     }
     for (WorkManager workManager in workManagers) {
-      workManager.applyChange(
-          Source.EMPTY_LIST, <Source>[source], Source.EMPTY_LIST);
+      workManager
+          .applyChange(const <Source>[], <Source>[source], const <Source>[]);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart b/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart
index 578c149..2d056ef 100644
--- a/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/frontend_resolution.dart
@@ -443,12 +443,16 @@
 
   @override
   void store(int offset, bool isSynthetic,
-      {int importIndex, Node reference, DartType type}) {
+      {int importIndex,
+      bool isNamespaceCombinatorReference = false,
+      Node reference,
+      DartType type}) {
 //    if (fileUri.toString().endsWith('test.dart')) {
 //      print('[store][offset: $offset][reference: $reference][type: $type]');
 //    }
     var encodedLocation = 2 * offset + (isSynthetic ? 1 : 0);
     resolution.kernelData[encodedLocation] = new ResolutionData(
+        isNamespaceCombinatorReference: isNamespaceCombinatorReference,
         isOutline: true,
         prefixInfo: importIndex,
         reference: reference,
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 487f11f..d5a934b 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -741,6 +741,9 @@
       if (directive.metadata.isNotEmpty) {
         applier.applyToAnnotations(directive);
       }
+      if (directive is NamespaceDirective) {
+        directive.combinators.accept(applier);
+      }
     }
     for (var declaration in unit.declarations) {
       if (declaration is ClassDeclaration) {
@@ -1133,8 +1136,9 @@
 
   @override
   Element translateReference(kernel.Node referencedNode,
-      {bool isWriteReference = false,
+      {bool isNamespaceCombinatorReference = false,
       bool isTypeReference = false,
+      bool isWriteReference = false,
       kernel.DartType inferredType,
       kernel.DartType receiverType}) {
     if (referencedNode == null) {
@@ -1169,6 +1173,9 @@
       throw new UnimplementedError(
           'TODO(paulberry): ${referencedNode.runtimeType}');
     }
+    if (isNamespaceCombinatorReference) {
+      return element;
+    }
     if (element is PropertyInducingElement) {
       PropertyInducingElement property = element;
       element = isWriteReference ? property.setter : property.getter;
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index cd0aa53..d014ecd 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -1084,6 +1084,15 @@
   }
 
   /**
+   * Check whether the values of the [first] and [second] nodes are [equal].
+   * Subclasses can override to throw.
+   */
+  bool failIfNotEqual(
+      AstNode first, Object firstValue, AstNode second, Object secondValue) {
+    return firstValue == secondValue;
+  }
+
+  /**
    * Check whether [second] is null. Subclasses can override to throw.
    */
   bool failIfNotNull(Object first, Object second) {
@@ -1186,7 +1195,7 @@
 
   @override
   bool visitAssertInitializer(AssertInitializer node) {
-    AssertStatement other = _other as AssertStatement;
+    AssertInitializer other = _other as AssertInitializer;
     return isEqualTokens(node.assertKeyword, other.assertKeyword) &&
         isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
         isEqualNodes(node.condition, other.condition) &&
@@ -1248,7 +1257,7 @@
   bool visitBooleanLiteral(BooleanLiteral node) {
     BooleanLiteral other = _other as BooleanLiteral;
     return isEqualTokens(node.literal, other.literal) &&
-        node.value == other.value;
+        failIfNotEqual(node, node.value, other, other.value);
   }
 
   @override
@@ -1448,7 +1457,7 @@
   bool visitDoubleLiteral(DoubleLiteral node) {
     DoubleLiteral other = _other as DoubleLiteral;
     return isEqualTokens(node.literal, other.literal) &&
-        node.value == other.value;
+        failIfNotEqual(node, node.value, other, other.value);
   }
 
   @override
@@ -1723,7 +1732,7 @@
   bool visitIntegerLiteral(IntegerLiteral node) {
     IntegerLiteral other = _other as IntegerLiteral;
     return isEqualTokens(node.literal, other.literal) &&
-        (node.value == other.value);
+        failIfNotEqual(node, node.value, other, other.value);
   }
 
   @override
@@ -1738,7 +1747,7 @@
   bool visitInterpolationString(InterpolationString node) {
     InterpolationString other = _other as InterpolationString;
     return isEqualTokens(node.contents, other.contents) &&
-        node.value == other.value;
+        failIfNotEqual(node, node.value, other, other.value);
   }
 
   @override
@@ -2006,7 +2015,7 @@
   bool visitSimpleStringLiteral(SimpleStringLiteral node) {
     SimpleStringLiteral other = _other as SimpleStringLiteral;
     return isEqualTokens(node.literal, other.literal) &&
-        (node.value == other.value);
+        failIfNotEqual(node, node.value, other, other.value);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index b9ac011e..15dc365 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -167,6 +167,7 @@
   /**
    * An empty list of objects.
    */
+  @deprecated
   static const List<DartObjectImpl> EMPTY_LIST = const <DartObjectImpl>[];
 
   @override
@@ -374,21 +375,19 @@
    */
   DartObjectImpl equalEqual(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
-    if (type != rightOperand.type) {
-      String typeName = type.name;
-      if (!(typeName == "bool" ||
-          typeName == "double" ||
-          typeName == "int" ||
-          typeName == "num" ||
-          typeName == "String" ||
-          typeName == "Null" ||
-          type.isDynamic)) {
-        throw new EvaluationException(
-            CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
-      }
+    if (isNull || rightOperand.isNull) {
+      return new DartObjectImpl(
+          typeProvider.boolType,
+          isNull && rightOperand.isNull
+              ? BoolState.TRUE_STATE
+              : BoolState.FALSE_STATE);
     }
-    return new DartObjectImpl(
-        typeProvider.boolType, _state.equalEqual(rightOperand._state));
+    if (isBoolNumStringOrNull) {
+      return new DartObjectImpl(
+          typeProvider.boolType, _state.equalEqual(rightOperand._state));
+    }
+    throw new EvaluationException(
+        CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
   }
 
   @override
@@ -573,18 +572,7 @@
    */
   DartObjectImpl notEqual(
       TypeProvider typeProvider, DartObjectImpl rightOperand) {
-    if (type != rightOperand.type) {
-      String typeName = type.name;
-      if (typeName != "bool" &&
-          typeName != "double" &&
-          typeName != "int" &&
-          typeName != "num" &&
-          typeName != "String") {
-        return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE);
-      }
-    }
-    return new DartObjectImpl(typeProvider.boolType,
-        _state.equalEqual(rightOperand._state).logicalNot());
+    return equalEqual(typeProvider, rightOperand).logicalNot(typeProvider);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index 8bd4925..236e332 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -1011,7 +1011,7 @@
   List<ElementAnnotation> _getElementAnnotations(
       NodeList<Annotation> metadata) {
     if (metadata.isEmpty) {
-      return ElementAnnotation.EMPTY_LIST;
+      return const <ElementAnnotation>[];
     }
     return metadata.map((Annotation a) => a.elementAnnotation).toList();
   }
@@ -1551,7 +1551,7 @@
   List<ElementAnnotation> _createElementAnnotations(
       NodeList<Annotation> annotations) {
     if (annotations.isEmpty) {
-      return ElementAnnotation.EMPTY_LIST;
+      return const <ElementAnnotation>[];
     }
     return annotations.map((Annotation a) {
       ElementAnnotationImpl elementAnnotation =
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index e99cc46..73e23a7 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -121,12 +121,18 @@
   }
 
   @override
-  bool get isEnum;
+  bool get isEnum => false;
+
+  @override
+  bool get isMixin => false;
 
   @override
   ElementKind get kind => ElementKind.CLASS;
 
   @override
+  List<InterfaceType> get superclassConstraints => const <InterfaceType>[];
+
+  @override
   T accept<T>(ElementVisitor<T> visitor) => visitor.visitClassElement(this);
 
   @override
@@ -837,9 +843,6 @@
   }
 
   @override
-  bool get isEnum => false;
-
-  @override
   bool get isMixinApplication {
     if (_kernel != null) {
       return _kernel.mixedInType != null;
@@ -1648,7 +1651,7 @@
           ..addAll(_explicitTopLevelVariables.implicitAccessors);
       }
     }
-    return _accessors ?? PropertyAccessorElement.EMPTY_LIST;
+    return _accessors ?? const <PropertyAccessorElement>[];
   }
 
   /**
@@ -1826,7 +1829,7 @@
         _variables = variables;
       }
     }
-    return _variables ?? TopLevelVariableElement.EMPTY_LIST;
+    return _variables ?? const <TopLevelVariableElement>[];
   }
 
   /**
@@ -2949,6 +2952,11 @@
    */
   static String _REQUIRED_VARIABLE_NAME = "required";
 
+  /**
+   * The name of the top-level variable used to mark a class as being sealed.
+   */
+  static String _SEALED_VARIABLE_NAME = "sealed";
+
   /// The name of the top-level variable used to mark a method as being
   /// visible for templates.
   static String _VISIBLE_FOR_TEMPLATE_VARIABLE_NAME = "visibleForTemplate";
@@ -3084,6 +3092,12 @@
           element.library?.name == _META_LIB_NAME;
 
   @override
+  bool get isSealed =>
+      element is PropertyAccessorElement &&
+      element.name == _SEALED_VARIABLE_NAME &&
+      element.library?.name == _META_LIB_NAME;
+
+  @override
   bool get isVisibleForTemplate =>
       element is PropertyAccessorElement &&
       element.name == _VISIBLE_FOR_TEMPLATE_VARIABLE_NAME &&
@@ -3306,6 +3320,10 @@
       metadata.any((ElementAnnotation annotation) => annotation.isRequired);
 
   @override
+  bool get hasSealed =>
+      metadata.any((ElementAnnotation annotation) => annotation.isSealed);
+
+  @override
   bool get hasVisibleForTemplate => metadata
       .any((ElementAnnotation annotation) => annotation.isVisibleForTemplate);
 
@@ -6410,7 +6428,7 @@
    * A list containing all of the compilation units that are included in this
    * library using a `part` directive.
    */
-  List<CompilationUnitElement> _parts = CompilationUnitElement.EMPTY_LIST;
+  List<CompilationUnitElement> _parts = const <CompilationUnitElement>[];
 
   /**
    * The element representing the synthetic function `loadLibrary` that is
@@ -6723,7 +6741,7 @@
             resynthesizerContext.linkedLibrary.importDependencies);
       }
     }
-    return _imports ?? ImportElement.EMPTY_LIST;
+    return _imports ?? const <ImportElement>[];
   }
 
   /**
@@ -7461,6 +7479,73 @@
 }
 
 /**
+ * A [ClassElementImpl] representing a mixin declaration.
+ */
+class MixinElementImpl extends ClassElementImpl {
+  // TODO(brianwilkerson) Consider creating an abstract superclass of
+  // ClassElementImpl that contains the portions of the API that this class
+  // needs, and make this class extend the new class.
+
+  /**
+   * A list containing all of the superclass constraints that are defined for
+   * the mixin.
+   */
+  List<InterfaceType> _superclassConstraints;
+
+  /**
+   * Initialize a newly created class element to have the given [name] at the
+   * given [offset] in the file that contains the declaration of this element.
+   */
+  MixinElementImpl(String name, int offset) : super(name, offset);
+
+  /**
+   * Initialize using the given kernel.
+   */
+  MixinElementImpl.forKernel(
+      CompilationUnitElementImpl enclosingUnit, kernel.Class kernel)
+      : super.forKernel(enclosingUnit, kernel);
+
+  /**
+   * Initialize a newly created class element to have the given [name].
+   */
+  MixinElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Initialize using the given serialized information.
+   */
+  MixinElementImpl.forSerialized(
+      UnlinkedClass unlinkedClass, CompilationUnitElementImpl enclosingUnit)
+      : super.forSerialized(unlinkedClass, enclosingUnit);
+
+  @override
+  bool get isMixin => true;
+
+  @override
+  List<InterfaceType> get superclassConstraints {
+    if (_superclassConstraints == null) {
+      if (_kernel != null) {
+        throw new UnimplementedError();
+      }
+      if (_unlinkedClass != null) {
+        throw new UnimplementedError();
+      }
+    }
+    return _superclassConstraints ?? const <InterfaceType>[];
+  }
+
+  void set superclassConstraints(List<InterfaceType> superclassConstraints) {
+    _assertNotResynthesized(_unlinkedClass);
+    // Note: if we are using kernel or the analysis driver, the set of
+    // superclass constraints has already been computed, and it's more accurate.
+    // So we only store superclass constraints if we are using the old task
+    // model.
+    if (_unlinkedClass == null && _kernel == null) {
+      _superclassConstraints = superclassConstraints;
+    }
+  }
+}
+
+/**
  * The constants for all of the modifiers defined by the Dart language and for a
  * few additional flags that are useful.
  *
@@ -7705,6 +7790,9 @@
   bool get hasRequired => false;
 
   @override
+  bool get hasSealed => false;
+
+  @override
   bool get hasVisibleForTemplate => false;
 
   @override
@@ -7898,7 +7986,7 @@
    * A list the array of executable elements that were used to compose this
    * element.
    */
-  List<ExecutableElement> _elements = MethodElement.EMPTY_LIST;
+  List<ExecutableElement> _elements = const <MethodElement>[];
 
   MultiplyInheritedMethodElementImpl(Identifier name) : super.forNode(name) {
     isSynthetic = true;
@@ -7923,7 +8011,7 @@
    * A list the array of executable elements that were used to compose this
    * element.
    */
-  List<ExecutableElement> _elements = PropertyAccessorElement.EMPTY_LIST;
+  List<ExecutableElement> _elements = const <PropertyAccessorElement>[];
 
   MultiplyInheritedPropertyAccessorElementImpl(Identifier name)
       : super.forNode(name) {
@@ -8921,7 +9009,7 @@
   String get identifier => "_${super.identifier}";
 
   @override
-  List<LibraryElement> get importedLibraries => LibraryElement.EMPTY_LIST;
+  List<LibraryElement> get importedLibraries => const <LibraryElement>[];
 
   @override
   ElementKind get kind => ElementKind.PREFIX;
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 6710524..331832d 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -56,6 +56,9 @@
   bool get hasRequired => actualElement.hasRequired;
 
   @override
+  bool get hasSealed => actualElement.hasSealed;
+
+  @override
   bool get hasStaticMember => actualElement.hasStaticMember;
 
   @override
@@ -71,6 +74,9 @@
   bool get isJS => actualElement.hasJS;
 
   @override
+  bool get isMixin => actualElement.isMixin;
+
+  @override
   bool get isMixinApplication => actualElement.isMixinApplication;
 
   @override
@@ -95,6 +101,10 @@
   List<InterfaceType> get mixins => actualElement.mixins;
 
   @override
+  List<InterfaceType> get superclassConstraints =>
+      actualElement.superclassConstraints;
+
+  @override
   InterfaceType get supertype => actualElement.supertype;
 
   @override
@@ -381,6 +391,9 @@
   bool get hasRequired => actualElement.hasRequired;
 
   @override
+  bool get hasSealed => actualElement.hasSealed;
+
+  @override
   bool get hasVisibleForTemplate => actualElement.hasVisibleForTemplate;
 
   @override
@@ -1032,7 +1045,7 @@
       super.enclosingElement as LibraryElement;
 
   @override
-  List<LibraryElement> get importedLibraries => LibraryElement.EMPTY_LIST;
+  List<LibraryElement> get importedLibraries => const <LibraryElement>[];
 
   @override
   ElementKind get kind => ElementKind.PREFIX;
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 0599412..5692687 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -419,6 +419,9 @@
   bool get hasRequired => _baseElement.hasRequired;
 
   @override
+  bool get hasSealed => _baseElement.hasSealed;
+
+  @override
   bool get hasVisibleForTemplate => _baseElement.hasVisibleForTemplate;
 
   @override
@@ -706,7 +709,7 @@
     if (type is FunctionType) {
       return type.parameters;
     }
-    return ParameterElement.EMPTY_LIST;
+    return const <ParameterElement>[];
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 5b6cbfa..e13eeac 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -103,14 +103,14 @@
   CircularFunctionTypeImpl() : super._circular();
 
   @override
-  List<ParameterElement> get baseParameters => ParameterElement.EMPTY_LIST;
+  List<ParameterElement> get baseParameters => const <ParameterElement>[];
 
   @override
   DartType get baseReturnType => DynamicTypeImpl.instance;
 
   @override
   List<TypeParameterElement> get boundTypeParameters =>
-      TypeParameterElement.EMPTY_LIST;
+      const <TypeParameterElement>[];
 
   @override
   FunctionTypedElement get element => null;
@@ -123,51 +123,51 @@
 
   @override
   List<FunctionTypeAliasElement> get newPrune =>
-      FunctionTypeAliasElement.EMPTY_LIST;
+      const <FunctionTypeAliasElement>[];
 
   @override
   List<String> get normalParameterNames => <String>[];
 
   @override
-  List<DartType> get normalParameterTypes => DartType.EMPTY_LIST;
+  List<DartType> get normalParameterTypes => const <DartType>[];
 
   @override
   List<String> get optionalParameterNames => <String>[];
 
   @override
-  List<DartType> get optionalParameterTypes => DartType.EMPTY_LIST;
+  List<DartType> get optionalParameterTypes => const <DartType>[];
 
   @override
-  List<ParameterElement> get parameters => ParameterElement.EMPTY_LIST;
+  List<ParameterElement> get parameters => const <ParameterElement>[];
 
   @override
   List<FunctionTypeAliasElement> get prunedTypedefs =>
-      FunctionTypeAliasElement.EMPTY_LIST;
+      const <FunctionTypeAliasElement>[];
 
   @override
   DartType get returnType => DynamicTypeImpl.instance;
 
   @override
-  List<DartType> get typeArguments => DartType.EMPTY_LIST;
+  List<DartType> get typeArguments => const <DartType>[];
 
   @override
-  List<TypeParameterElement> get typeFormals => TypeParameterElement.EMPTY_LIST;
+  List<TypeParameterElement> get typeFormals => const <TypeParameterElement>[];
 
   @override
   List<TypeParameterElement> get typeParameters =>
-      TypeParameterElement.EMPTY_LIST;
+      const <TypeParameterElement>[];
 
   @override
   bool get _isInstantiated => false;
 
   @override
-  List<ParameterElement> get _parameters => ParameterElement.EMPTY_LIST;
+  List<ParameterElement> get _parameters => const <ParameterElement>[];
 
   @override
   DartType get _returnType => DynamicTypeImpl.instance;
 
   @override
-  List<DartType> get _typeArguments => DartType.EMPTY_LIST;
+  List<DartType> get _typeArguments => const <DartType>[];
 
   @override
   void set _typeArguments(List<DartType> arguments) {
@@ -176,7 +176,7 @@
 
   @override
   List<TypeParameterElement> get _typeParameters =>
-      TypeParameterElement.EMPTY_LIST;
+      const <TypeParameterElement>[];
 
   @override
   void set _typeParameters(List<TypeParameterElement> parameters) {
@@ -799,7 +799,7 @@
   void _freeVariablesInFunctionType(
       FunctionType type, Set<TypeParameterType> free) {
     // Make some fresh variables to avoid capture.
-    List<DartType> typeArgs = DartType.EMPTY_LIST;
+    List<DartType> typeArgs = const <DartType>[];
     if (type.typeFormals.isNotEmpty) {
       typeArgs = new List<DartType>.from(type.typeFormals.map((e) =>
           new TypeParameterTypeImpl(new TypeParameterElementImpl(e.name, -1))));
@@ -851,7 +851,7 @@
     // For now though, this is a pretty quick operation.
     if (g.typeFormals.isEmpty) {
       assert(g == f);
-      return DartType.EMPTY_LIST;
+      return const <DartType>[];
     }
     assert(f.typeFormals.isEmpty);
     assert(g.typeFormals.length <= f.typeArguments.length);
@@ -1149,7 +1149,7 @@
   /**
    * A list containing the actual types of the type arguments.
    */
-  List<DartType> _typeArguments = DartType.EMPTY_LIST;
+  List<DartType> _typeArguments = const <DartType>[];
 
   /**
    * If not `null` and [_typeArguments] is `null`, the actual type arguments
@@ -2756,7 +2756,7 @@
       List<TypeParameterElement> typeParameters) {
     int count = typeParameters.length;
     if (count == 0) {
-      return TypeParameterType.EMPTY_LIST;
+      return const <TypeParameterType>[];
     }
     List<TypeParameterType> types = new List<TypeParameterType>(count);
     for (int i = 0; i < count; i++) {
@@ -3061,7 +3061,7 @@
       // make it generic, which will allow it to return List<DartType> instead
       // of List<TypeParameterType>.
       if (typeParameters.isEmpty) {
-        _typeArguments = DartType.EMPTY_LIST;
+        _typeArguments = const <DartType>[];
       } else {
         _typeArguments = new List<DartType>.from(
             typeParameters.map((t) => t.type),
@@ -3074,12 +3074,12 @@
   @override
   List<TypeParameterElement> get typeFormals {
     if (_isInstantiated || element == null) {
-      return TypeParameterElement.EMPTY_LIST;
+      return const <TypeParameterElement>[];
     }
     List<TypeParameterElement> baseTypeFormals = element.typeParameters;
     int formalCount = baseTypeFormals.length;
     if (formalCount == 0) {
-      return TypeParameterElement.EMPTY_LIST;
+      return const <TypeParameterElement>[];
     }
 
     // Create type formals with specialized bounds.
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart
index 88291aa..cd3d985 100644
--- a/pkg/analyzer/lib/src/dart/element/wrapped.dart
+++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -76,6 +76,9 @@
   bool get hasRequired => wrappedUnit.hasRequired;
 
   @override
+  bool get hasSealed => wrappedUnit.hasSealed;
+
+  @override
   bool get hasVisibleForTemplate => wrappedUnit.hasVisibleForTemplate;
 
   @override
@@ -252,6 +255,9 @@
   bool get hasRequired => wrappedImport.hasRequired;
 
   @override
+  bool get hasSealed => wrappedImport.hasSealed;
+
+  @override
   bool get hasVisibleForTemplate => wrappedImport.hasVisibleForTemplate;
 
   @override
@@ -446,6 +452,9 @@
   bool get hasRequired => wrappedLib.hasRequired;
 
   @override
+  bool get hasSealed => wrappedLib.hasSealed;
+
+  @override
   bool get hasVisibleForTemplate => wrappedLib.hasVisibleForTemplate;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 97341b4..73b516c 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -297,6 +297,19 @@
       correction: "Remove @required.");
 
   /**
+   * This hint is generated anywhere where `@sealed` annotates something other
+   * than a class or mixin.
+   *
+   * Parameters:
+   * 0: the name of the member
+   */
+  static const HintCode INVALID_SEALED_ANNOTATION = const HintCode(
+      'INVALID_SEALED_ANNOTATION',
+      "The member '{0}' is annotated with @sealed but only classes and mixins "
+      "can be annotated with it.",
+      correction: "Remove @sealed.");
+
+  /**
    * This hint is generated anywhere where a member annotated with `@protected`
    * is used outside an instance member of a subclass.
    *
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 2fde37f..72568c0 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -7,6 +7,11 @@
 import 'package:analyzer/dart/ast/standard_ast_factory.dart' as standard;
 import 'package:analyzer/dart/ast/token.dart' show Token, TokenType;
 import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/dart/ast/ast.dart'
+    show
+        ClassDeclarationImpl,
+        ClassOrMixinDeclarationImpl,
+        MixinDeclarationImpl;
 import 'package:analyzer/src/fasta/error_converter.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:front_end/src/fasta/parser.dart'
@@ -69,7 +74,10 @@
   bool parseGenericMethodComments = false;
 
   /// The class currently being parsed, or `null` if no class is being parsed.
-  ClassDeclaration classDeclaration;
+  ClassDeclarationImpl classDeclaration;
+
+  /// The mixin currently being parsed, or `null` if no mixin is being parsed.
+  MixinDeclarationImpl mixinDeclaration;
 
   /// If true, this is building a full AST. Otherwise, only create method
   /// bodies.
@@ -215,7 +223,8 @@
       for (int i = 1; i < parts.length - 1; i++) {
         var part = parts[i];
         if (part is Token) {
-          elements.add(ast.interpolationString(part, part.lexeme));
+          elements.add(ast.interpolationString(
+              part, unescape(part.lexeme, quote, part, this)));
         } else if (part is InterpolationExpression) {
           elements.add(part);
         } else {
@@ -1745,13 +1754,15 @@
     assert(optional('}', rightBracket));
     debugEvent("ClassOrMixinBody");
 
-    classDeclaration.leftBracket = leftBracket;
-    classDeclaration.rightBracket = rightBracket;
+    ClassOrMixinDeclarationImpl declaration =
+        classDeclaration ?? mixinDeclaration;
+    declaration.leftBracket = leftBracket;
+    declaration.rightBracket = rightBracket;
   }
 
   @override
   void beginClassDeclaration(Token begin, Token abstractToken, Token name) {
-    assert(classDeclaration == null);
+    assert(classDeclaration == null && mixinDeclaration == null);
     push(new _Modifiers()..abstractKeyword = abstractToken);
   }
 
@@ -1796,7 +1807,7 @@
   void handleClassHeader(Token begin, Token classKeyword, Token nativeToken) {
     assert(optional('class', classKeyword));
     assert(optionalOrNull('native', nativeToken));
-    assert(classDeclaration == null);
+    assert(classDeclaration == null && mixinDeclaration == null);
     debugEvent("ClassHeader");
 
     NativeClause nativeClause;
@@ -1828,6 +1839,7 @@
       <ClassMember>[],
       null, // rightBracket
     );
+
     classDeclaration.nativeClause = nativeClause;
     declarations.add(classDeclaration);
   }
@@ -1869,6 +1881,58 @@
   }
 
   @override
+  void beginMixinDeclaration(Token mixinKeyword, Token name) {
+    assert(classDeclaration == null && mixinDeclaration == null);
+  }
+
+  @override
+  void handleMixinOn(Token onKeyword, int typeCount) {
+    assert(optionalOrNull('on', onKeyword));
+    debugEvent("MixinOn");
+
+    if (onKeyword != null) {
+      List<TypeName> types = popTypedList(typeCount);
+      push(ast.onClause(onKeyword, types));
+    } else {
+      push(NullValue.IdentifierList);
+    }
+  }
+
+  @override
+  void handleMixinHeader(Token mixinKeyword) {
+    assert(optional('mixin', mixinKeyword));
+    assert(classDeclaration == null && mixinDeclaration == null);
+    debugEvent("MixinHeader");
+
+    ImplementsClause implementsClause = pop(NullValue.IdentifierList);
+    OnClause onClause = pop(NullValue.IdentifierList);
+    TypeParameterList typeParameters = pop();
+    SimpleIdentifier name = pop();
+    List<Annotation> metadata = pop();
+    Comment comment = _findComment(metadata, mixinKeyword);
+
+    mixinDeclaration = ast.mixinDeclaration(
+      comment,
+      metadata,
+      mixinKeyword,
+      name,
+      typeParameters,
+      onClause,
+      implementsClause,
+      null, // leftBracket
+      <ClassMember>[],
+      null, // rightBracket
+    );
+    declarations.add(mixinDeclaration);
+  }
+
+  @override
+  void endMixinDeclaration(Token token) {
+    debugEvent("MixinDeclaration");
+    mixinDeclaration = null;
+  }
+
+  @override
   void beginNamedMixinApplication(
       Token begin, Token abstractToken, Token name) {
     push(new _Modifiers()..abstractKeyword = abstractToken);
@@ -2096,20 +2160,21 @@
           ast.simpleIdentifier(typeName.identifier.token, isDeclaration: true);
     }
 
-    classDeclaration.members.add(ast.constructorDeclaration(
-        comment,
-        metadata,
-        modifiers?.externalKeyword,
-        modifiers?.finalConstOrVarKeyword,
-        factoryKeyword,
-        ast.simpleIdentifier(returnType.token),
-        period,
-        name,
-        parameters,
-        separator,
-        null,
-        redirectedConstructor,
-        body));
+    (classDeclaration ?? mixinDeclaration).members.add(
+        ast.constructorDeclaration(
+            comment,
+            metadata,
+            modifiers?.externalKeyword,
+            modifiers?.finalConstOrVarKeyword,
+            factoryKeyword,
+            ast.simpleIdentifier(returnType.token),
+            period,
+            name,
+            parameters,
+            separator,
+            null,
+            redirectedConstructor,
+            body));
   }
 
   void endFieldInitializer(Token assignment, Token token) {
@@ -2312,6 +2377,9 @@
           leftParen, <FormalParameter>[], null, null, rightParen);
     }
 
+    ClassOrMixinDeclarationImpl declaration =
+        classDeclaration ?? mixinDeclaration;
+
     void constructor(
         SimpleIdentifier prefixOrName, Token period, SimpleIdentifier name) {
       if (typeParameters != null) {
@@ -2332,7 +2400,7 @@
         handleRecoverableError(messageConstructorWithReturnType,
             returnType.beginToken, returnType.beginToken);
       }
-      classDeclaration.members.add(ast.constructorDeclaration(
+      ConstructorDeclaration constructor = ast.constructorDeclaration(
           comment,
           metadata,
           modifiers?.externalKeyword,
@@ -2345,7 +2413,11 @@
           separator,
           initializers,
           redirectedConstructor,
-          body));
+          body);
+      declaration.members.add(constructor);
+      if (mixinDeclaration != null) {
+        // TODO (danrubel): Report an error if this is a mixin declaration.
+      }
     }
 
     void method(Token operatorKeyword, SimpleIdentifier name) {
@@ -2357,7 +2429,7 @@
             messageConstMethod, modifiers.constKeyword, modifiers.constKeyword);
       }
       checkFieldFormalParameters(parameters);
-      classDeclaration.members.add(ast.methodDeclaration(
+      declaration.members.add(ast.methodDeclaration(
           comment,
           metadata,
           modifiers?.externalKeyword,
@@ -2372,7 +2444,7 @@
     }
 
     if (name is SimpleIdentifier) {
-      if (name.name == classDeclaration.name.name && getOrSet == null) {
+      if (name.name == declaration.name.name && getOrSet == null) {
         constructor(name, null, null);
       } else if (initializers.isNotEmpty) {
         constructor(name, null, null);
@@ -2504,7 +2576,7 @@
     Token covariantKeyword = modifiers?.covariantKeyword;
     List<Annotation> metadata = pop();
     Comment comment = _findComment(metadata, beginToken);
-    classDeclaration.members.add(ast.fieldDeclaration2(
+    (classDeclaration ?? mixinDeclaration).members.add(ast.fieldDeclaration2(
         comment: comment,
         metadata: metadata,
         covariantKeyword: covariantKeyword,
@@ -2517,9 +2589,15 @@
   AstNode finishFields() {
     debugEvent("finishFields");
 
-    return classDeclaration != null
-        ? classDeclaration.members.removeAt(classDeclaration.members.length - 1)
-        : declarations.removeLast();
+    if (classDeclaration != null) {
+      return classDeclaration.members
+          .removeAt(classDeclaration.members.length - 1);
+    } else if (mixinDeclaration != null) {
+      return mixinDeclaration.members
+          .removeAt(mixinDeclaration.members.length - 1);
+    } else {
+      return declarations.removeLast();
+    }
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/fasta/resolution_applier.dart b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
index 6a416b6..3c913ce 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_applier.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
@@ -919,8 +919,9 @@
       return _translatePrefixInfo(data.prefixInfo);
     }
     return _typeContext.translateReference(data.reference,
-        isWriteReference: data.isWriteReference,
+        isNamespaceCombinatorReference: data.isNamespaceCombinatorReference,
         isTypeReference: data.isTypeReference,
+        isWriteReference: data.isWriteReference,
         inferredType: data.inferredType,
         receiverType: data.receiverType);
   }
@@ -977,8 +978,9 @@
 
   /// Return the analyzer [Element] for the given kernel node.
   Element translateReference(kernel.Node referencedNode,
-      {bool isWriteReference = false,
+      {bool isNamespaceCombinatorReference = false,
       bool isTypeReference = false,
+      bool isWriteReference = false,
       kernel.DartType inferredType,
       kernel.DartType receiverType});
 
diff --git a/pkg/analyzer/lib/src/fasta/resolution_storer.dart b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
index 81ff987..04e1c84 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_storer.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
@@ -18,6 +18,7 @@
   final DartType invokeType;
   final bool isExplicitCall;
   final bool isImplicitCall;
+  final bool isNamespaceCombinatorReference;
   final bool isOutline;
   final bool isPrefixReference;
   final bool isTypeReference;
@@ -36,6 +37,7 @@
       this.invokeType,
       this.isExplicitCall = false,
       this.isImplicitCall = false,
+      this.isNamespaceCombinatorReference = false,
       this.isOutline = false,
       this.isPrefixReference = false,
       this.isTypeReference = false,
@@ -573,12 +575,14 @@
   void propertyAssign(
       ExpressionJudgment judgment,
       int location,
+      bool isSyntheticLhs,
       DartType receiverType,
       Node writeMember,
       DartType writeContext,
       Node combiner,
       DartType inferredType) {
     _store(location,
+        isSynthetic: isSyntheticLhs,
         isWriteReference: true,
         reference: writeMember,
         writeContext: writeContext,
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index d34072c..8d1810d 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -93,6 +93,7 @@
   /**
    * An empty list of contexts.
    */
+  @deprecated
   static const List<AnalysisContext> EMPTY_LIST = const <AnalysisContext>[];
 
   /**
@@ -1468,14 +1469,9 @@
   bool useCFE = false;
 
   @override
-  bool get previewDart2 => true;
-
-  // A no-op setter.
-  set previewDart2(bool value) {}
-
-  @override
   bool disableCacheFlushing = false;
 
+  // A no-op setter.
   /**
    * A flag indicating whether implicit casts are allowed in [strongMode]
    * (they are always allowed in Dart 1.0 mode).
@@ -1656,6 +1652,11 @@
   }
 
   @override
+  bool get previewDart2 => true;
+
+  set previewDart2(bool value) {}
+
+  @override
   Uint32List get signature {
     if (_signature == null) {
       ApiSignature buffer = new ApiSignature();
@@ -1984,6 +1985,7 @@
   /**
    * An empty list of change notices.
    */
+  @deprecated
   static const List<ChangeNoticeImpl> EMPTY_LIST = const <ChangeNoticeImpl>[];
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index e916ae7..b88db95 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -3897,8 +3897,10 @@
    * assigned variable in a for-in statement.
    */
   void _checkForInIterable(ForEachStatement node) {
+    DeclaredIdentifier loopVariable = node.loopVariable;
+
     // Ignore malformed for statements.
-    if (node.identifier == null && node.loopVariable == null) {
+    if (node.identifier == null && loopVariable == null) {
       return;
     }
 
@@ -3912,7 +3914,7 @@
     }
 
     // The type of the loop variable.
-    SimpleIdentifier variable = node.identifier ?? node.loopVariable.identifier;
+    SimpleIdentifier variable = node.identifier ?? loopVariable.identifier;
     DartType variableType = getStaticType(variable);
 
     // TODO(mfairhurst) Check and guard against `for(void x in _)`?
@@ -3940,6 +3942,19 @@
       }
     }
 
+    if (loopVariable != null) {
+      if (loopVariable.isConst) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE, loopVariable);
+      }
+    } else if (node.identifier != null) {
+      Element variableElement = node.identifier.staticElement;
+      if (variableElement is VariableElement && variableElement.isConst) {
+        _errorReporter.reportErrorForNode(
+            CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE, node.identifier);
+      }
+    }
+
     if (bestIterableType == null) {
       _errorReporter.reportTypeErrorForNode(
           StaticTypeWarningCode.FOR_IN_OF_INVALID_TYPE,
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 49d1e51..124183c 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1574,6 +1574,13 @@
       // arguments should be constants
       _validateConstantArguments(argumentList);
     }
+    if (node.elementAnnotation?.isSealed == true &&
+        !(node.parent is ClassDeclaration ||
+            node.parent is ClassTypeAlias ||
+            node.parent is MixinDeclaration)) {
+      _errorReporter.reportErrorForNode(
+          HintCode.INVALID_SEALED_ANNOTATION, node.parent, [node.element.name]);
+    }
     return null;
   }
 
@@ -2728,7 +2735,7 @@
 
   List<PropertyAccessorElement> get accessors {
     if (_accessors == null) {
-      return PropertyAccessorElement.EMPTY_LIST;
+      return const <PropertyAccessorElement>[];
     }
     List<PropertyAccessorElement> result = _accessors;
     _accessors = null;
@@ -2737,7 +2744,7 @@
 
   List<ConstructorElement> get constructors {
     if (_constructors == null) {
-      return ConstructorElement.EMPTY_LIST;
+      return const <ConstructorElement>[];
     }
     List<ConstructorElement> result = _constructors;
     _constructors = null;
@@ -2746,7 +2753,7 @@
 
   List<ClassElement> get enums {
     if (_enums == null) {
-      return ClassElement.EMPTY_LIST;
+      return const <ClassElement>[];
     }
     List<ClassElement> result = _enums;
     _enums = null;
@@ -2755,7 +2762,7 @@
 
   List<FieldElement> get fields {
     if (_fields == null) {
-      return FieldElement.EMPTY_LIST;
+      return const <FieldElement>[];
     }
     List<FieldElement> result = _fields;
     _fields = null;
@@ -2764,7 +2771,7 @@
 
   List<FieldElement> get fieldsWithoutFlushing {
     if (_fields == null) {
-      return FieldElement.EMPTY_LIST;
+      return const <FieldElement>[];
     }
     List<FieldElement> result = _fields;
     return result;
@@ -2772,7 +2779,7 @@
 
   List<FunctionElement> get functions {
     if (_functions == null) {
-      return FunctionElement.EMPTY_LIST;
+      return const <FunctionElement>[];
     }
     List<FunctionElement> result = _functions;
     _functions = null;
@@ -2781,7 +2788,7 @@
 
   List<LabelElement> get labels {
     if (_labels == null) {
-      return LabelElement.EMPTY_LIST;
+      return const <LabelElement>[];
     }
     List<LabelElement> result = _labels;
     _labels = null;
@@ -2790,7 +2797,7 @@
 
   List<LocalVariableElement> get localVariables {
     if (_localVariables == null) {
-      return LocalVariableElement.EMPTY_LIST;
+      return const <LocalVariableElement>[];
     }
     List<LocalVariableElement> result = _localVariables;
     _localVariables = null;
@@ -2799,7 +2806,7 @@
 
   List<MethodElement> get methods {
     if (_methods == null) {
-      return MethodElement.EMPTY_LIST;
+      return const <MethodElement>[];
     }
     List<MethodElement> result = _methods;
     _methods = null;
@@ -2808,7 +2815,7 @@
 
   List<ParameterElement> get parameters {
     if (_parameters == null) {
-      return ParameterElement.EMPTY_LIST;
+      return const <ParameterElement>[];
     }
     List<ParameterElement> result = _parameters;
     _parameters = null;
@@ -2817,7 +2824,7 @@
 
   List<TopLevelVariableElement> get topLevelVariables {
     if (_topLevelVariables == null) {
-      return TopLevelVariableElement.EMPTY_LIST;
+      return const <TopLevelVariableElement>[];
     }
     List<TopLevelVariableElement> result = _topLevelVariables;
     _topLevelVariables = null;
@@ -2826,7 +2833,7 @@
 
   List<FunctionTypeAliasElement> get typeAliases {
     if (_typeAliases == null) {
-      return FunctionTypeAliasElement.EMPTY_LIST;
+      return const <FunctionTypeAliasElement>[];
     }
     List<FunctionTypeAliasElement> result = _typeAliases;
     _typeAliases = null;
@@ -2835,7 +2842,7 @@
 
   List<TypeParameterElement> get typeParameters {
     if (_typeParameters == null) {
-      return TypeParameterElement.EMPTY_LIST;
+      return const <TypeParameterElement>[];
     }
     List<TypeParameterElement> result = _typeParameters;
     _typeParameters = null;
@@ -2844,7 +2851,7 @@
 
   List<ClassElement> get types {
     if (_types == null) {
-      return ClassElement.EMPTY_LIST;
+      return const <ClassElement>[];
     }
     List<ClassElement> result = _types;
     _types = null;
@@ -6606,8 +6613,8 @@
         ts is StrongTypeSystemImpl) {
       return ts.inferGenericFunctionOrType<FunctionType>(
           uninstantiatedType,
-          ParameterElement.EMPTY_LIST,
-          DartType.EMPTY_LIST,
+          const <ParameterElement>[],
+          const <DartType>[],
           InferenceContext.getContext(inferenceNode),
           downwards: true,
           errorReporter: errorReporter,
@@ -8172,51 +8179,20 @@
     }
     DartType type = null;
     if (element is ClassElement) {
+      _setElement(typeName, element);
       type = element.type;
-      // In non-strong mode `FutureOr<T>` is treated as `dynamic`
-      if (!typeSystem.isStrong && type.isDartAsyncFutureOr) {
-        type = dynamicType;
-        _setElement(typeName, type.element);
-        typeName.staticType = type;
-        node.type = type;
-        if (argumentList != null) {
-          NodeList<TypeAnnotation> arguments = argumentList.arguments;
-          if (arguments.length != 1) {
-            reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node,
-                [typeName.name, 1, arguments.length]);
-          }
-        }
-        return;
-      }
+    } else if (element == DynamicElementImpl.instance) {
       _setElement(typeName, element);
-    } else if (element is TypeDefiningElement &&
-        element.kind == ElementKind.DYNAMIC) {
-//      if (argumentList != null) {
-//        // Type parameters cannot have type arguments.
-//        // TODO(mfairhurst) Report this error.
-//        resolver.reportError(ResolverErrorCode.?, keyType);
-//      }
-      _setElement(typeName, element);
-      typeName.staticType = element.type;
-      node.type = element.type;
-      return;
+      type = DynamicTypeImpl.instance;
     } else if (element is FunctionTypeAliasElement) {
       _setElement(typeName, element);
       type = element.type;
     } else if (element is TypeParameterElement) {
       _setElement(typeName, element);
       type = element.type;
-//      if (argumentList != null) {
-//        // Type parameters cannot have type arguments.
-//        // TODO(brianwilkerson) Report this error.
-//        //      resolver.reportError(ResolverErrorCode.?, keyType);
-//      }
     } else if (element is MultiplyDefinedElement) {
       List<Element> elements = element.conflictingElements;
       type = _getTypeWhenMultiplyDefined(elements);
-      if (type != null) {
-        node.type = type;
-      }
     } else {
       // The name does not represent a type.
       RedirectingConstructorKind redirectingConstructorKind;
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 4d19bff..d6c07ff 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -185,8 +185,7 @@
   }
 
   static ExportElementImpl exportFor(LibraryElement exportedLibrary,
-      [List<NamespaceCombinator> combinators =
-          NamespaceCombinator.EMPTY_LIST]) {
+      [List<NamespaceCombinator> combinators = const <NamespaceCombinator>[]]) {
     ExportElementImpl spec = new ExportElementImpl(-1);
     spec.exportedLibrary = exportedLibrary;
     spec.combinators = combinators;
@@ -407,8 +406,7 @@
 
   static ImportElementImpl importFor(
       LibraryElement importedLibrary, PrefixElement prefix,
-      [List<NamespaceCombinator> combinators =
-          NamespaceCombinator.EMPTY_LIST]) {
+      [List<NamespaceCombinator> combinators = const <NamespaceCombinator>[]]) {
     ImportElementImpl spec = new ImportElementImpl(0);
     spec.importedLibrary = importedLibrary;
     spec.prefix = prefix;
@@ -436,7 +434,7 @@
       [List<DartType> argumentTypes]) {
     MethodElementImpl method = new MethodElementImpl(methodName, 0);
     if (argumentTypes == null) {
-      method.parameters = ParameterElement.EMPTY_LIST;
+      method.parameters = const <ParameterElement>[];
     } else {
       int count = argumentTypes.length;
       List<ParameterElement> parameters = new List<ParameterElement>(count);
@@ -593,7 +591,7 @@
   static List<TypeParameterElement> typeParameters(List<String> names) {
     int count = names.length;
     if (count == 0) {
-      return TypeParameterElement.EMPTY_LIST;
+      return const <TypeParameterElement>[];
     }
     List<TypeParameterElementImpl> typeParameters =
         new List<TypeParameterElementImpl>(count);
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 2960e79..2a7ac3e 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -2022,7 +2022,7 @@
     } else if (type is InterfaceType) {
       return type.typeParameters;
     } else {
-      return TypeParameterElement.EMPTY_LIST;
+      return const <TypeParameterElement>[];
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 2d7db0f..18dc9b8 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -189,7 +189,7 @@
 
     if (result == TYPE_PROVIDER) {
       entry.setValue(result as ResultDescriptor<TypeProvider>,
-          _resynthesizer.typeProvider, TargetedResult.EMPTY_LIST);
+          _resynthesizer.typeProvider, const <TargetedResult>[]);
       return true;
     }
 
@@ -202,7 +202,7 @@
         if (lineStarts.isNotEmpty) {
           LineInfo lineInfo = new LineInfo(lineStarts);
           entry.setValue(result as ResultDescriptor<LineInfo>, lineInfo,
-              TargetedResult.EMPTY_LIST);
+              const <TargetedResult>[]);
           return true;
         }
       }
@@ -217,7 +217,7 @@
     if (result == CONSTANT_EXPRESSION_RESOLVED &&
         target is ConstantEvaluationTarget) {
       entry.setValue(
-          result as ResultDescriptor<bool>, true, TargetedResult.EMPTY_LIST);
+          result as ResultDescriptor<bool>, true, const <TargetedResult>[]);
       return true;
     }
     // Provide results for Source.
@@ -237,17 +237,17 @@
         LibraryElement libraryElement =
             resynthesizer.getLibraryElement(uriString);
         entry.setValue(result as ResultDescriptor<LibraryElement>,
-            libraryElement, TargetedResult.EMPTY_LIST);
+            libraryElement, const <TargetedResult>[]);
         return true;
       } else if (result == READY_LIBRARY_ELEMENT2 ||
           result == READY_LIBRARY_ELEMENT6 ||
           result == READY_LIBRARY_ELEMENT7) {
         entry.setValue(
-            result as ResultDescriptor<bool>, true, TargetedResult.EMPTY_LIST);
+            result as ResultDescriptor<bool>, true, const <TargetedResult>[]);
         return true;
       } else if (result == MODIFICATION_TIME) {
         entry.setValue(
-            result as ResultDescriptor<int>, 0, TargetedResult.EMPTY_LIST);
+            result as ResultDescriptor<int>, 0, const <TargetedResult>[]);
         return true;
       } else if (result == SOURCE_KIND) {
         UnlinkedUnit unlinked = _dataStore.unlinkedMap[uriString];
@@ -255,7 +255,7 @@
           entry.setValue(
               result as ResultDescriptor<SourceKind>,
               unlinked.isPartOf ? SourceKind.PART : SourceKind.LIBRARY,
-              TargetedResult.EMPTY_LIST);
+              const <TargetedResult>[]);
           return true;
         }
         return false;
@@ -268,7 +268,7 @@
                   context.sourceFactory.resolveUri(target, libraryUriString))
               .toList(growable: false);
           entry.setValue(result as ResultDescriptor<List<Source>>,
-              librarySources, TargetedResult.EMPTY_LIST);
+              librarySources, const <TargetedResult>[]);
           return true;
         }
         return false;
@@ -286,7 +286,7 @@
           result == CREATED_RESOLVED_UNIT10 ||
           result == CREATED_RESOLVED_UNIT11) {
         entry.setValue(
-            result as ResultDescriptor<bool>, true, TargetedResult.EMPTY_LIST);
+            result as ResultDescriptor<bool>, true, const <TargetedResult>[]);
         return true;
       }
       if (result == COMPILATION_UNIT_ELEMENT) {
@@ -296,14 +296,14 @@
             new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
         if (unit != null) {
           entry.setValue(result as ResultDescriptor<CompilationUnitElement>,
-              unit, TargetedResult.EMPTY_LIST);
+              unit, const <TargetedResult>[]);
           return true;
         }
       }
     } else if (target is VariableElement) {
       if (result == INFERRED_STATIC_VARIABLE) {
         entry.setValue(result as ResultDescriptor<VariableElement>, target,
-            TargetedResult.EMPTY_LIST);
+            const <TargetedResult>[]);
         return true;
       }
     }
diff --git a/pkg/analyzer/lib/src/task/api/dart.dart b/pkg/analyzer/lib/src/task/api/dart.dart
index 44ef9b8..d8f28ff 100644
--- a/pkg/analyzer/lib/src/task/api/dart.dart
+++ b/pkg/analyzer/lib/src/task/api/dart.dart
@@ -29,7 +29,7 @@
  */
 final ListResultDescriptor<Source> EXPLICITLY_IMPORTED_LIBRARIES =
     new ListResultDescriptor<Source>(
-        'EXPLICITLY_IMPORTED_LIBRARIES', Source.EMPTY_LIST);
+        'EXPLICITLY_IMPORTED_LIBRARIES', const <Source>[]);
 
 /**
  * The sources of the libraries that are exported from a library.
@@ -40,7 +40,7 @@
  * The result is only available for [Source]s representing a library.
  */
 final ListResultDescriptor<Source> EXPORTED_LIBRARIES =
-    new ListResultDescriptor<Source>('EXPORTED_LIBRARIES', Source.EMPTY_LIST);
+    new ListResultDescriptor<Source>('EXPORTED_LIBRARIES', const <Source>[]);
 
 /**
  * The sources of the libraries that are implicitly or explicitly imported into
@@ -52,7 +52,7 @@
  * The result is only available for [Source]s representing a library.
  */
 final ListResultDescriptor<Source> IMPORTED_LIBRARIES =
-    new ListResultDescriptor<Source>('IMPORTED_LIBRARIES', Source.EMPTY_LIST);
+    new ListResultDescriptor<Source>('IMPORTED_LIBRARIES', const <Source>[]);
 
 /**
  * The sources of the parts that are included in a library.
@@ -63,7 +63,7 @@
  * The result is only available for [Source]s representing a library.
  */
 final ListResultDescriptor<Source> INCLUDED_PARTS =
-    new ListResultDescriptor<Source>('INCLUDED_PARTS', Source.EMPTY_LIST);
+    new ListResultDescriptor<Source>('INCLUDED_PARTS', const <Source>[]);
 
 /**
  * A flag specifying whether a library is launchable.
@@ -129,7 +129,7 @@
  * The result is only available for [Source]s representing a library.
  */
 final ListResultDescriptor<Source> UNITS =
-    new ListResultDescriptor<Source>('UNITS', Source.EMPTY_LIST);
+    new ListResultDescriptor<Source>('UNITS', const <Source>[]);
 
 /**
  * A specific compilation unit in a specific library.
@@ -140,6 +140,7 @@
  * change if a single part is included in more than one library.
  */
 class LibrarySpecificUnit implements AnalysisTarget {
+  @deprecated
   static const List<LibrarySpecificUnit> EMPTY_LIST =
       const <LibrarySpecificUnit>[];
 
diff --git a/pkg/analyzer/lib/src/task/api/html.dart b/pkg/analyzer/lib/src/task/api/html.dart
index 4005bcc..8a7cae8 100644
--- a/pkg/analyzer/lib/src/task/api/html.dart
+++ b/pkg/analyzer/lib/src/task/api/html.dart
@@ -24,4 +24,4 @@
  * The sources of the Dart libraries referenced by an HTML file.
  */
 final ListResultDescriptor<Source> REFERENCED_LIBRARIES =
-    new ListResultDescriptor<Source>('REFERENCED_LIBRARIES', Source.EMPTY_LIST);
+    new ListResultDescriptor<Source>('REFERENCED_LIBRARIES', const <Source>[]);
diff --git a/pkg/analyzer/lib/src/task/api/model.dart b/pkg/analyzer/lib/src/task/api/model.dart
index 0ba6aec..703d8b8 100644
--- a/pkg/analyzer/lib/src/task/api/model.dart
+++ b/pkg/analyzer/lib/src/task/api/model.dart
@@ -510,6 +510,7 @@
   /**
    * An empty list of results.
    */
+  @deprecated
   static final List<TargetedResult> EMPTY_LIST = const <TargetedResult>[];
 
   /**
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index ca7b0eb..7ab1b66 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -190,7 +190,7 @@
  * The result is only available for [Source]s representing a compilation unit.
  */
 final ListResultDescriptor<Source> CONTAINING_LIBRARIES =
-    new ListResultDescriptor<Source>('CONTAINING_LIBRARIES', Source.EMPTY_LIST);
+    new ListResultDescriptor<Source>('CONTAINING_LIBRARIES', const <Source>[]);
 
 /**
  * The flag specifying that [RESOLVED_UNIT] has been been computed for this
@@ -575,7 +575,7 @@
  */
 final ListResultDescriptor<LibrarySpecificUnit> LIBRARY_SPECIFIC_UNITS =
     new ListResultDescriptor<LibrarySpecificUnit>(
-        'LIBRARY_SPECIFIC_UNITS', LibrarySpecificUnit.EMPTY_LIST);
+        'LIBRARY_SPECIFIC_UNITS', const <LibrarySpecificUnit>[]);
 
 /**
  * The analysis errors associated with a compilation unit in a specific library.
@@ -662,7 +662,7 @@
  * The result is only available for [Source]s representing a library.
  */
 final ListResultDescriptor<Source> REFERENCED_SOURCES =
-    new ListResultDescriptor<Source>('REFERENCED_SOURCES', Source.EMPTY_LIST);
+    new ListResultDescriptor<Source>('REFERENCED_SOURCES', const <Source>[]);
 
 /**
  * The list of [ConstantEvaluationTarget]s on which error verification depends.
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 5225f5e..2a27c15 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -202,7 +202,7 @@
     }
     List<Source> libraries = partLibrariesMap[part];
     libraries ??= _getLibrariesContainingPartFromResultProvider(part);
-    return libraries?.toList() ?? Source.EMPTY_LIST;
+    return libraries?.toList() ?? const <Source>[];
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index 8de0347e..c72d99f 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -23,7 +23,7 @@
  * The Dart scripts that are embedded in an HTML file.
  */
 final ListResultDescriptor<DartScript> DART_SCRIPTS =
-    new ListResultDescriptor<DartScript>('DART_SCRIPTS', DartScript.EMPTY_LIST);
+    new ListResultDescriptor<DartScript>('DART_SCRIPTS', const <DartScript>[]);
 
 /**
  * The errors found while parsing an HTML file.
@@ -39,7 +39,8 @@
   /**
    * An empty list of scripts.
    */
-  static final List<DartScript> EMPTY_LIST = <DartScript>[];
+  @deprecated
+  static final List<DartScript> EMPTY_LIST = const <DartScript>[];
 
   /**
    * The source containing this script.
@@ -157,9 +158,9 @@
     // Record outputs.
     //
     outputs[REFERENCED_LIBRARIES] =
-        libraries.isEmpty ? Source.EMPTY_LIST : libraries;
+        libraries.isEmpty ? const <Source>[] : libraries;
     outputs[DART_SCRIPTS] =
-        inlineScripts.isEmpty ? DartScript.EMPTY_LIST : inlineScripts;
+        inlineScripts.isEmpty ? const <DartScript>[] : inlineScripts;
   }
 
   /**
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index 76f3f4e..2bb645b 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -325,7 +325,7 @@
     ];
     htmlUnit.functions = <FunctionElement>[
       ElementFactory.functionElement3("query", elementElement.type,
-          <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST)
+          <ClassElement>[provider.stringType.element], const <ClassElement>[])
     ];
     TopLevelVariableElementImpl document =
         ElementFactory.topLevelVariableElement3(
@@ -347,14 +347,14 @@
         "cos",
         provider.doubleType,
         <ClassElement>[provider.numType.element],
-        ClassElement.EMPTY_LIST);
+        const <ClassElement>[]);
     TopLevelVariableElement ln10Element =
         ElementFactory.topLevelVariableElement3(
             "LN10", true, false, provider.doubleType);
     TypeParameterElement maxT =
         ElementFactory.typeParameterWithType('T', provider.numType);
     FunctionElementImpl maxElement = ElementFactory.functionElement3(
-        "max", maxT.type, [maxT, maxT], ClassElement.EMPTY_LIST);
+        "max", maxT.type, [maxT, maxT], const <ClassElement>[]);
     maxElement.typeParameters = [maxT];
     maxElement.type = new FunctionTypeImpl(maxElement);
     TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3(
@@ -373,12 +373,12 @@
         "sin",
         provider.doubleType,
         <ClassElement>[provider.numType.element],
-        ClassElement.EMPTY_LIST);
+        const <ClassElement>[]);
     FunctionElement sqrtElement = ElementFactory.functionElement3(
         "sqrt",
         provider.doubleType,
         <ClassElement>[provider.numType.element],
-        ClassElement.EMPTY_LIST);
+        const <ClassElement>[]);
     mathUnit.accessors = <PropertyAccessorElement>[
       ln10Element.getter,
       piElement.getter
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
index d6835c5..0cd7e62 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
@@ -301,6 +301,12 @@
 
   @override
   @failingTest
+  test_forInWithConstVariable_forEach_identifier() async {
+    return super.test_forInWithConstVariable_forEach_identifier();
+  }
+
+  @override
+  @failingTest
   test_genericFunctionTypeArgument_class() async {
     await super.test_genericFunctionTypeArgument_class();
   }
@@ -431,42 +437,12 @@
 
   @override
   @failingTest
-  test_implementsRepeated() async {
-    await super.test_implementsRepeated();
-  }
-
-  @override
-  @failingTest
   test_implementsRepeated_3times() async {
     await super.test_implementsRepeated_3times();
   }
 
   @override
   @failingTest
-  test_implementsSuperClass() async {
-    await super.test_implementsSuperClass();
-  }
-
-  @override
-  @failingTest
-  test_implementsSuperClass_Object() async {
-    await super.test_implementsSuperClass_Object();
-  }
-
-  @override
-  @failingTest
-  test_implementsSuperClass_Object_typeAlias() async {
-    await super.test_implementsSuperClass_Object_typeAlias();
-  }
-
-  @override
-  @failingTest
-  test_implementsSuperClass_typeAlias() async {
-    await super.test_implementsSuperClass_typeAlias();
-  }
-
-  @override
-  @failingTest
   test_implicitThisReferenceInInitializer_field() async {
     await super.test_implicitThisReferenceInInitializer_field();
   }
@@ -1219,53 +1195,17 @@
 
   @override
   @failingTest
-  test_superInInvalidContext_binaryExpression() async {
-    await super.test_superInInvalidContext_binaryExpression();
-  }
-
-  @override
-  @failingTest
   test_superInInvalidContext_constructorFieldInitializer() async {
     await super.test_superInInvalidContext_constructorFieldInitializer();
   }
 
   @override
   @failingTest
-  test_superInInvalidContext_factoryConstructor() async {
-    await super.test_superInInvalidContext_factoryConstructor();
-  }
-
-  @override
-  @failingTest
   test_superInInvalidContext_instanceVariableInitializer() async {
     await super.test_superInInvalidContext_instanceVariableInitializer();
   }
 
   @override
-  @failingTest
-  test_superInInvalidContext_staticMethod() async {
-    await super.test_superInInvalidContext_staticMethod();
-  }
-
-  @override
-  @failingTest
-  test_superInInvalidContext_staticVariableInitializer() async {
-    await super.test_superInInvalidContext_staticVariableInitializer();
-  }
-
-  @override
-  @failingTest
-  test_superInInvalidContext_topLevelFunction() async {
-    await super.test_superInInvalidContext_topLevelFunction();
-  }
-
-  @override
-  @failingTest
-  test_superInInvalidContext_topLevelVariableInitializer() async {
-    await super.test_superInInvalidContext_topLevelVariableInitializer();
-  }
-
-  @override
   @failingTest // Deliberately only reports one of the expected errors.
   test_superInRedirectingConstructor_superRedirection() async {
     await super.test_superInRedirectingConstructor_superRedirection();
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 81013ce..d2202d1 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -2965,6 +2965,27 @@
     verify([source]);
   }
 
+  test_forInWithConstVariable_forEach_identifier() async {
+    Source source = addSource(r'''
+f() {
+  const x = 0;
+  for (x in [0, 1, 2]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
+    verify([source]);
+  }
+
+  test_forInWithConstVariable_forEach_loopVariable() async {
+    Source source = addSource(r'''
+f() {
+  for (const x in [0, 1, 2]) {}
+}''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
+    verify([source]);
+  }
+
   test_fromEnvironment_bool_badArgs() async {
     Source source = addSource(r'''
 var b1 = const bool.fromEnvironment(1);
@@ -7467,7 +7488,11 @@
   test_superInInvalidContext_binaryExpression() async {
     Source source = addSource("var v = super + 0;");
     await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    assertErrors(
+        source,
+        useCFE
+            ? [CompileTimeErrorCode.SUPER_AS_EXPRESSION]
+            : [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
     // no verify(), 'super.v' is not resolved
   }
 
@@ -7497,7 +7522,11 @@
   }
 }''');
     await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    assertErrors(
+        source,
+        useCFE
+            ? [CompileTimeErrorCode.SUPER_AS_EXPRESSION]
+            : [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
     // no verify(), 'super.m' is not resolved
   }
 
@@ -7523,7 +7552,11 @@
   static n() { return super.m(); }
 }''');
     await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    assertErrors(
+        source,
+        useCFE
+            ? [CompileTimeErrorCode.SUPER_AS_EXPRESSION]
+            : [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
     // no verify(), 'super.m' is not resolved
   }
 
@@ -7536,7 +7569,11 @@
   static int b = super.a;
 }''');
     await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    assertErrors(
+        source,
+        useCFE
+            ? [CompileTimeErrorCode.SUPER_AS_EXPRESSION]
+            : [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
     // no verify(), 'super.a' is not resolved
   }
 
@@ -7546,14 +7583,22 @@
   super.f();
 }''');
     await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    assertErrors(
+        source,
+        useCFE
+            ? [CompileTimeErrorCode.SUPER_AS_EXPRESSION]
+            : [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
     // no verify(), 'super.f' is not resolved
   }
 
   test_superInInvalidContext_topLevelVariableInitializer() async {
     Source source = addSource("var v = super.y;");
     await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
+    assertErrors(
+        source,
+        useCFE
+            ? [CompileTimeErrorCode.SUPER_AS_EXPRESSION]
+            : [CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT]);
     // no verify(), 'super.y' is not resolved
   }
 
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 75c40b4..f1d150d 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -192,7 +192,7 @@
 
   static void assertEvent(SourcesChangedEvent event,
       {bool wereSourcesAdded: false,
-      List<Source> changedSources: Source.EMPTY_LIST,
+      List<Source> changedSources: const <Source>[],
       bool wereSourcesRemoved: false}) {
     expect(event.wereSourcesAdded, wereSourcesAdded);
     expect(event.changedSources, changedSources);
@@ -205,7 +205,7 @@
 
   void assertEvent(
       {bool wereSourcesAdded: false,
-      List<Source> changedSources: Source.EMPTY_LIST,
+      List<Source> changedSources: const <Source>[],
       bool wereSourcesRemovedOrDeleted: false}) {
     if (actualEvents.isEmpty) {
       fail('Expected event but found none');
diff --git a/pkg/analyzer/test/generated/hint_code_kernel_test.dart b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
index 3e9f85c..073e8c5 100644
--- a/pkg/analyzer/test/generated/hint_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
@@ -83,18 +83,6 @@
     return super.test_deprecatedFunction_mixin2();
   }
 
-  @failingTest
-  @override
-  test_duplicateShownHiddenName_hidden() {
-    return super.test_duplicateShownHiddenName_hidden();
-  }
-
-  @failingTest
-  @override
-  test_duplicateShownHiddenName_shown() {
-    return super.test_duplicateShownHiddenName_shown();
-  }
-
   @override
   @failingTest
   test_invalidRequiredParam_on_named_parameter_with_default() async {
@@ -169,6 +157,13 @@
 
   @failingTest
   @override
+  // Failing due to https://github.com/dart-lang/sdk/issues/34249
+  test_invalidSealedAnnotation_onMixinApplication() async {
+    return super.test_invalidSealedAnnotation_onMixinApplication();
+  }
+
+  @failingTest
+  @override
   test_strongMode_downCastCompositeHint() async {
     return super.test_strongMode_downCastCompositeHint();
   }
@@ -184,28 +179,4 @@
   test_unusedImport_inComment_libraryDirective() async {
     return super.test_unusedImport_inComment_libraryDirective();
   }
-
-  @failingTest
-  @override
-  test_unusedShownName() async {
-    return super.test_unusedShownName();
-  }
-
-  @failingTest
-  @override
-  test_unusedShownName_as() async {
-    return super.test_unusedShownName_as();
-  }
-
-  @failingTest
-  @override
-  test_unusedShownName_duplicates() async {
-    return super.test_unusedShownName_duplicates();
-  }
-
-  @failingTest
-  @override
-  test_unusedShownName_topLevelVariable() async {
-    return super.test_unusedShownName_topLevelVariable();
-  }
 }
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 7235f38..36f7faa 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -38,6 +38,7 @@
 const _MustCallSuper mustCallSuper = const _MustCallSuper();
 const _Protected protected = const _Protected();
 const Required required = const Required();
+const _Sealed sealed = const _Sealed();
 const _VisibleForTesting visibleForTesting = const _VisibleForTesting();
 
 class Immutable {
@@ -63,6 +64,9 @@
   final String reason;
   const Required([this.reason]);
 }
+class _Sealed {
+  const _Sealed();
+}
 class _VisibleForTesting {
   const _VisibleForTesting();
 }
@@ -1654,6 +1658,55 @@
     verify([source]);
   }
 
+  test_invalidSealedAnnotation_onNonClass() async {
+    Source source = addNamedSource('/lib1.dart', r'''
+import 'package:meta/meta.dart';
+
+@sealed m({a = 1}) => null;
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [HintCode.INVALID_SEALED_ANNOTATION]);
+    verify([source]);
+  }
+
+  test_invalidSealedAnnotation_onClass() async {
+    Source source = addNamedSource('/lib1.dart', r'''
+import 'package:meta/meta.dart';
+
+@sealed class A {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  test_invalidSealedAnnotation_onMixinApplication() async {
+    Source source = addNamedSource('/lib1.dart', r'''
+import 'package:meta/meta.dart';
+
+abstract class A {}
+
+abstract class B {}
+
+@sealed abstract class M = A with B;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  @failingTest
+  test_invalidSealedAnnotation_onMixin() async {
+    Source source = addNamedSource('/lib1.dart', r'''
+import 'package:meta/meta.dart';
+
+@sealed mixin M {}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   test_invalidUseOfProtectedMember_closure() async {
     Source source = addNamedSource('/lib1.dart', r'''
 import 'package:meta/meta.dart';
diff --git a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
index 82c52fb..f4f1192 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
@@ -40,20 +40,6 @@
 
   @override
   @failingTest
-  @AnalyzerProblem('https://github.com/dart-lang/sdk/issues/33636')
-  test_ambiguousImport_showCombinator() async {
-    return super.test_ambiguousImport_showCombinator();
-  }
-
-  @override
-  @failingTest
-  @FastaProblem('https://github.com/dart-lang/sdk/issues/33795')
-  test_annotated_partOfDeclaration() async {
-    return super.test_annotated_partOfDeclaration();
-  }
-
-  @override
-  @failingTest
   @FastaProblem('https://github.com/dart-lang/sdk/issues/31604')
   test_commentReference_beforeConstructor() async {
     return super.test_commentReference_beforeConstructor();
@@ -191,12 +177,6 @@
 
   @override
   @failingTest
-  test_optionalNew_rewrite() {
-    return super.test_optionalNew_rewrite();
-  }
-
-  @override
-  @failingTest
   test_undefinedIdentifier_synthetic_whenMethodName() async {
     return super.test_undefinedIdentifier_synthetic_whenMethodName();
   }
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index a2a00ea..58d3b70 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -1487,9 +1487,6 @@
 
   test_constEvalTypeBoolNumString_equal() async {
     Source source = addSource(r'''
-class A {
-  const A();
-}
 class B {
   final v;
   const B.a1(bool p) : v = p == true;
@@ -1509,6 +1506,8 @@
   const B.c5(String p) : v = p == '';
   const B.n1(num p) : v = p == null;
   const B.n2(num p) : v = null == p;
+  const B.n3(Object p) : v = p == null;
+  const B.n4(Object p) : v = null == p;
 }''');
     await computeAnalysisResult(source);
     assertNoErrors(source);
@@ -1516,9 +1515,6 @@
 
   test_constEvalTypeBoolNumString_notEqual() async {
     Source source = addSource(r'''
-class A {
-  const A();
-}
 class B {
   final v;
   const B.a1(bool p) : v = p != true;
@@ -1538,13 +1534,15 @@
   const B.c5(String p) : v = p != '';
   const B.n1(num p) : v = p != null;
   const B.n2(num p) : v = null != p;
+  const B.n3(Object p) : v = p != null;
+  const B.n4(Object p) : v = null != p;
 }''');
     await computeAnalysisResult(source);
     assertNoErrors(source);
     verify([source]);
   }
 
-  test_constEvelTypeNum_String() async {
+  test_constEvAlTypeNum_String() async {
     Source source = addSource(r'''
 const String A = 'a';
 const String B = A + 'b';
diff --git a/pkg/analyzer/test/generated/parser_fasta_listener.dart b/pkg/analyzer/test/generated/parser_fasta_listener.dart
index 40f2c23..d61baab 100644
--- a/pkg/analyzer/test/generated/parser_fasta_listener.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_listener.dart
@@ -393,6 +393,12 @@
   }
 
   @override
+  void beginMixinDeclaration(Token mixinKeyword, Token name) {
+    super.beginMixinDeclaration(mixinKeyword, name);
+    begin('MixinDeclaration');
+  }
+
+  @override
   void beginNamedFunctionExpression(Token token) {
     super.beginNamedFunctionExpression(token);
     begin('NamedFunctionExpression');
@@ -903,6 +909,12 @@
   }
 
   @override
+  void endMixinDeclaration(Token token) {
+    end('MixinDeclaration');
+    super.endMixinDeclaration(token);
+  }
+
+  @override
   void endNamedFunctionExpression(Token endToken) {
     end('NamedFunctionExpression');
     super.endNamedFunctionExpression(endToken);
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index db49d52..118210a 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1038,6 +1038,16 @@
     StringLiteral literal = expression.expression;
     expect(literal.stringValue, 'a');
   }
+
+  @failingTest
+  @override
+  void test_parseCommentReferences_skipLink_direct_multiLine() =>
+      super.test_parseCommentReferences_skipLink_direct_multiLine();
+
+  @failingTest
+  @override
+  void test_parseCommentReferences_skipLink_reference_multiLine() =>
+      super.test_parseCommentReferences_skipLink_reference_multiLine();
 }
 
 /**
@@ -1140,4 +1150,197 @@
     allowNativeClause = false;
     test_parseClassDeclaration_native();
   }
+
+  void test_parseMixinDeclaration_empty() {
+    createParser('mixin A {}');
+    _parserProxy.fastaParser.isMixinSupportEnabled = true;
+    MixinDeclaration declaration = parseFullCompilationUnitMember();
+    expect(declaration, isNotNull);
+    assertNoErrors();
+    expect(declaration.metadata, isEmpty);
+    expect(declaration.documentationComment, isNull);
+    expect(declaration.onClause, isNull);
+    expect(declaration.implementsClause, isNull);
+    expect(declaration.mixinKeyword, isNotNull);
+    expect(declaration.leftBracket, isNotNull);
+    expect(declaration.name.name, 'A');
+    expect(declaration.members, hasLength(0));
+    expect(declaration.rightBracket, isNotNull);
+    expect(declaration.typeParameters, isNull);
+  }
+
+  void test_parseMixinDeclaration_implements() {
+    createParser('mixin A implements B {}');
+    _parserProxy.fastaParser.isMixinSupportEnabled = true;
+    MixinDeclaration declaration = parseFullCompilationUnitMember();
+    expect(declaration, isNotNull);
+    assertNoErrors();
+    expect(declaration.metadata, isEmpty);
+    expect(declaration.documentationComment, isNull);
+    expect(declaration.onClause, isNull);
+    ImplementsClause implementsClause = declaration.implementsClause;
+    expect(implementsClause.implementsKeyword, isNotNull);
+    NodeList<TypeName> interfaces = implementsClause.interfaces;
+    expect(interfaces, hasLength(1));
+    expect(interfaces[0].name.name, 'B');
+    expect(interfaces[0].typeArguments, isNull);
+    expect(declaration.mixinKeyword, isNotNull);
+    expect(declaration.leftBracket, isNotNull);
+    expect(declaration.name.name, 'A');
+    expect(declaration.members, hasLength(0));
+    expect(declaration.rightBracket, isNotNull);
+    expect(declaration.typeParameters, isNull);
+  }
+
+  void test_parseMixinDeclaration_implements2() {
+    createParser('mixin A implements B<T>, C {}');
+    _parserProxy.fastaParser.isMixinSupportEnabled = true;
+    MixinDeclaration declaration = parseFullCompilationUnitMember();
+    expect(declaration, isNotNull);
+    assertNoErrors();
+    expect(declaration.metadata, isEmpty);
+    expect(declaration.documentationComment, isNull);
+    expect(declaration.onClause, isNull);
+    ImplementsClause implementsClause = declaration.implementsClause;
+    expect(implementsClause.implementsKeyword, isNotNull);
+    NodeList<TypeName> interfaces = implementsClause.interfaces;
+    expect(interfaces, hasLength(2));
+    expect(interfaces[0].name.name, 'B');
+    expect(interfaces[0].typeArguments.arguments, hasLength(1));
+    expect(interfaces[1].name.name, 'C');
+    expect(interfaces[1].typeArguments, isNull);
+    expect(declaration.mixinKeyword, isNotNull);
+    expect(declaration.leftBracket, isNotNull);
+    expect(declaration.name.name, 'A');
+    expect(declaration.members, hasLength(0));
+    expect(declaration.rightBracket, isNotNull);
+    expect(declaration.typeParameters, isNull);
+  }
+
+  void test_parseMixinDeclaration_metadata() {
+    createParser('@Z mixin A {}');
+    _parserProxy.fastaParser.isMixinSupportEnabled = true;
+    MixinDeclaration declaration = parseFullCompilationUnitMember();
+    expect(declaration, isNotNull);
+    assertNoErrors();
+    NodeList<Annotation> metadata = declaration.metadata;
+    expect(metadata, hasLength(1));
+    expect(metadata[0].name.name, 'Z');
+    expect(declaration.documentationComment, isNull);
+    expect(declaration.onClause, isNull);
+    expect(declaration.implementsClause, isNull);
+    expect(declaration.mixinKeyword, isNotNull);
+    expect(declaration.leftBracket, isNotNull);
+    expect(declaration.name.name, 'A');
+    expect(declaration.members, hasLength(0));
+    expect(declaration.rightBracket, isNotNull);
+    expect(declaration.typeParameters, isNull);
+  }
+
+  void test_parseMixinDeclaration_on() {
+    createParser('mixin A on B {}');
+    _parserProxy.fastaParser.isMixinSupportEnabled = true;
+    MixinDeclaration declaration = parseFullCompilationUnitMember();
+    expect(declaration, isNotNull);
+    assertNoErrors();
+    expect(declaration.metadata, isEmpty);
+    expect(declaration.documentationComment, isNull);
+    OnClause onClause = declaration.onClause;
+    expect(onClause.onKeyword, isNotNull);
+    NodeList<TypeName> constraints = onClause.superclassConstraints;
+    expect(constraints, hasLength(1));
+    expect(constraints[0].name.name, 'B');
+    expect(constraints[0].typeArguments, isNull);
+    expect(declaration.implementsClause, isNull);
+    expect(declaration.mixinKeyword, isNotNull);
+    expect(declaration.leftBracket, isNotNull);
+    expect(declaration.name.name, 'A');
+    expect(declaration.members, hasLength(0));
+    expect(declaration.rightBracket, isNotNull);
+    expect(declaration.typeParameters, isNull);
+  }
+
+  void test_parseMixinDeclaration_on2() {
+    createParser('mixin A on B, C<T> {}');
+    _parserProxy.fastaParser.isMixinSupportEnabled = true;
+    MixinDeclaration declaration = parseFullCompilationUnitMember();
+    expect(declaration, isNotNull);
+    assertNoErrors();
+    expect(declaration.metadata, isEmpty);
+    expect(declaration.documentationComment, isNull);
+    OnClause onClause = declaration.onClause;
+    expect(onClause.onKeyword, isNotNull);
+    NodeList<TypeName> constraints = onClause.superclassConstraints;
+    expect(constraints, hasLength(2));
+    expect(constraints[0].name.name, 'B');
+    expect(constraints[0].typeArguments, isNull);
+    expect(constraints[1].name.name, 'C');
+    expect(constraints[1].typeArguments.arguments, hasLength(1));
+    expect(declaration.implementsClause, isNull);
+    expect(declaration.mixinKeyword, isNotNull);
+    expect(declaration.leftBracket, isNotNull);
+    expect(declaration.name.name, 'A');
+    expect(declaration.members, hasLength(0));
+    expect(declaration.rightBracket, isNotNull);
+    expect(declaration.typeParameters, isNull);
+  }
+
+  void test_parseMixinDeclaration_onAndImplements() {
+    createParser('mixin A on B implements C {}');
+    _parserProxy.fastaParser.isMixinSupportEnabled = true;
+    MixinDeclaration declaration = parseFullCompilationUnitMember();
+    expect(declaration, isNotNull);
+    assertNoErrors();
+    expect(declaration.metadata, isEmpty);
+    expect(declaration.documentationComment, isNull);
+    OnClause onClause = declaration.onClause;
+    expect(onClause.onKeyword, isNotNull);
+    NodeList<TypeName> constraints = onClause.superclassConstraints;
+    expect(constraints, hasLength(1));
+    expect(constraints[0].name.name, 'B');
+    expect(constraints[0].typeArguments, isNull);
+    ImplementsClause implementsClause = declaration.implementsClause;
+    expect(implementsClause.implementsKeyword, isNotNull);
+    NodeList<TypeName> interfaces = implementsClause.interfaces;
+    expect(interfaces, hasLength(1));
+    expect(interfaces[0].name.name, 'C');
+    expect(interfaces[0].typeArguments, isNull);
+    expect(declaration.mixinKeyword, isNotNull);
+    expect(declaration.leftBracket, isNotNull);
+    expect(declaration.name.name, 'A');
+    expect(declaration.members, hasLength(0));
+    expect(declaration.rightBracket, isNotNull);
+    expect(declaration.typeParameters, isNull);
+  }
+
+  void test_parseMixinDeclaration_simple() {
+    createParser('''
+mixin A {
+  int f;
+  int get g => f;
+  set s(int v) {f = v;}
+  int add(int v) => f = f + v;
+}''');
+    _parserProxy.fastaParser.isMixinSupportEnabled = true;
+    MixinDeclaration declaration = parseFullCompilationUnitMember();
+    expect(declaration, isNotNull);
+    assertNoErrors();
+    expect(declaration.metadata, isEmpty);
+    expect(declaration.documentationComment, isNull);
+    expect(declaration.onClause, isNull);
+    expect(declaration.implementsClause, isNull);
+    expect(declaration.mixinKeyword, isNotNull);
+    expect(declaration.leftBracket, isNotNull);
+    expect(declaration.name.name, 'A');
+    expect(declaration.members, hasLength(4));
+    expect(declaration.rightBracket, isNotNull);
+    expect(declaration.typeParameters, isNull);
+  }
+
+  void test_parseMixinDeclaration_withDocumentationComment() {
+    createParser('/// Doc\nmixin M {}');
+    _parserProxy.fastaParser.isMixinSupportEnabled = true;
+    MixinDeclaration declaration = parseFullCompilationUnitMember();
+    expectCommentText(declaration.documentationComment, '/// Doc');
+  }
 }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 8a3a172..1a32e5f 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -13555,16 +13555,6 @@
     expect(declaration.metadata, hasLength(2));
   }
 
-  void test_parseCommentAndMetadata_mm() {
-    createParser('@A @B(x) class C {}');
-    CompilationUnit unit = parser.parseCompilationUnit2();
-    expectNotNullIfNoErrors(unit);
-    assertNoErrors();
-    ClassDeclaration declaration = unit.declarations[0];
-    expect(declaration.documentationComment, isNull);
-    expect(declaration.metadata, hasLength(2));
-  }
-
   void test_parseCommentAndMetadata_mix1() {
     createParser(r'''
 /**
@@ -13662,6 +13652,16 @@
     expect(tokens[0].lexeme, contains('aaa'));
   }
 
+  void test_parseCommentAndMetadata_mm() {
+    createParser('@A @B(x) class C {}');
+    CompilationUnit unit = parser.parseCompilationUnit2();
+    expectNotNullIfNoErrors(unit);
+    assertNoErrors();
+    ClassDeclaration declaration = unit.declarations[0];
+    expect(declaration.documentationComment, isNull);
+    expect(declaration.metadata, hasLength(2));
+  }
+
   void test_parseCommentAndMetadata_none() {
     createParser('class C {}');
     CompilationUnit unit = parser.parseCompilationUnit2();
@@ -13686,75 +13686,6 @@
     expect(declaration.metadata, isEmpty);
   }
 
-  void test_parseCommentReferences_33738() {
-    CompilationUnit unit =
-        parseCompilationUnit('/** [String] */ abstract class Foo {}');
-    ClassDeclaration clazz = unit.declarations[0];
-    Comment comment = clazz.documentationComment;
-    expect(clazz.isAbstract, isTrue);
-    List<CommentReference> references = comment.references;
-    expect(references, hasLength(1));
-    CommentReference reference = references[0];
-    expect(reference, isNotNull);
-    expect(reference.identifier, isNotNull);
-    expect(reference.offset, 5);
-  }
-
-  void test_parseCommentReferences_beforeAnnotation() {
-    CompilationUnit unit = parseCompilationUnit('''
-/// See [int] and [String]
-/// and [Object].
-@Annotation
-abstract class Foo {}
-''');
-    ClassDeclaration clazz = unit.declarations[0];
-    Comment comment = clazz.documentationComment;
-    expect(clazz.isAbstract, isTrue);
-    List<CommentReference> references = comment.references;
-    expect(references, hasLength(3));
-
-    expectReference(int index, String expectedText, int expectedOffset) {
-      CommentReference reference = references[index];
-      expect(reference.identifier.name, expectedText);
-      expect(reference.offset, expectedOffset);
-    }
-
-    expectReference(0, 'int', 9);
-    expectReference(1, 'String', 19);
-    expectReference(2, 'Object', 36);
-  }
-
-  void test_parseCommentReferences_complex() {
-    CompilationUnit unit = parseCompilationUnit('''
-/// This dartdoc comment [should] be ignored
-@Annotation
-/// This dartdoc comment is [included].
-// a non dartdoc comment [inbetween]
-/// See [int] and [String] but `not [a]`
-/// ```
-/// This [code] block should be ignored
-/// ```
-/// and [Object].
-abstract class Foo {}
-''');
-    ClassDeclaration clazz = unit.declarations[0];
-    Comment comment = clazz.documentationComment;
-    expect(clazz.isAbstract, isTrue);
-    List<CommentReference> references = comment.references;
-    expect(references, hasLength(4));
-
-    expectReference(int index, String expectedText, int expectedOffset) {
-      CommentReference reference = references[index];
-      expect(reference.identifier.name, expectedText);
-      expect(reference.offset, expectedOffset);
-    }
-
-    expectReference(0, 'included', 86);
-    expectReference(1, 'int', 143);
-    expectReference(2, 'String', 153);
-    expectReference(3, 'Object', 240);
-  }
-
   void test_parseCommentReference_new_prefixed() {
     createParser('');
     CommentReference reference = parseCommentReference('new a.b', 7);
@@ -13910,6 +13841,75 @@
     expect(identifier.offset, 5);
   }
 
+  void test_parseCommentReferences_33738() {
+    CompilationUnit unit =
+        parseCompilationUnit('/** [String] */ abstract class Foo {}');
+    ClassDeclaration clazz = unit.declarations[0];
+    Comment comment = clazz.documentationComment;
+    expect(clazz.isAbstract, isTrue);
+    List<CommentReference> references = comment.references;
+    expect(references, hasLength(1));
+    CommentReference reference = references[0];
+    expect(reference, isNotNull);
+    expect(reference.identifier, isNotNull);
+    expect(reference.offset, 5);
+  }
+
+  void test_parseCommentReferences_beforeAnnotation() {
+    CompilationUnit unit = parseCompilationUnit('''
+/// See [int] and [String]
+/// and [Object].
+@Annotation
+abstract class Foo {}
+''');
+    ClassDeclaration clazz = unit.declarations[0];
+    Comment comment = clazz.documentationComment;
+    expect(clazz.isAbstract, isTrue);
+    List<CommentReference> references = comment.references;
+    expect(references, hasLength(3));
+
+    expectReference(int index, String expectedText, int expectedOffset) {
+      CommentReference reference = references[index];
+      expect(reference.identifier.name, expectedText);
+      expect(reference.offset, expectedOffset);
+    }
+
+    expectReference(0, 'int', 9);
+    expectReference(1, 'String', 19);
+    expectReference(2, 'Object', 36);
+  }
+
+  void test_parseCommentReferences_complex() {
+    CompilationUnit unit = parseCompilationUnit('''
+/// This dartdoc comment [should] be ignored
+@Annotation
+/// This dartdoc comment is [included].
+// a non dartdoc comment [inbetween]
+/// See [int] and [String] but `not [a]`
+/// ```
+/// This [code] block should be ignored
+/// ```
+/// and [Object].
+abstract class Foo {}
+''');
+    ClassDeclaration clazz = unit.declarations[0];
+    Comment comment = clazz.documentationComment;
+    expect(clazz.isAbstract, isTrue);
+    List<CommentReference> references = comment.references;
+    expect(references, hasLength(4));
+
+    expectReference(int index, String expectedText, int expectedOffset) {
+      CommentReference reference = references[index];
+      expect(reference.identifier.name, expectedText);
+      expect(reference.offset, expectedOffset);
+    }
+
+    expectReference(0, 'included', 86);
+    expectReference(1, 'int', 143);
+    expectReference(2, 'String', 153);
+    expectReference(3, 'Object', 240);
+  }
+
   void test_parseCommentReferences_multiLine() {
     DocumentationCommentToken token = new DocumentationCommentToken(
         TokenType.MULTI_LINE_COMMENT, "/** xxx [a] yyy [bb] zzz */", 3);
@@ -14136,10 +14136,17 @@
     expect(reference.offset, 27);
   }
 
-  void test_parseCommentReferences_skipLinkDefinition() {
+  void test_parseCommentReferences_skipLink_direct_multiLine() {
     List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
-      new DocumentationCommentToken(TokenType.MULTI_LINE_COMMENT,
-          "/** [a]: http://www.google.com (Google) [b] zzz */", 3)
+      new DocumentationCommentToken(
+          TokenType.MULTI_LINE_COMMENT,
+          '''
+/**
+ * [a link split across multiple
+ * lines](http://www.google.com) [b] zzz
+ */
+''',
+          3)
     ];
     createParser('');
     List<CommentReference> references = parser.parseCommentReferences(tokens);
@@ -14149,10 +14156,10 @@
     CommentReference reference = references[0];
     expect(reference, isNotNull);
     expect(reference.identifier, isNotNull);
-    expect(reference.offset, 44);
+    expect(reference.offset, 74);
   }
 
-  void test_parseCommentReferences_skipLinked() {
+  void test_parseCommentReferences_skipLink_direct_singleLine() {
     List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
       new DocumentationCommentToken(TokenType.MULTI_LINE_COMMENT,
           "/** [a](http://www.google.com) [b] zzz */", 3)
@@ -14168,7 +14175,30 @@
     expect(reference.offset, 35);
   }
 
-  void test_parseCommentReferences_skipReferenceLink() {
+  void test_parseCommentReferences_skipLink_reference_multiLine() {
+    List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
+      new DocumentationCommentToken(
+          TokenType.MULTI_LINE_COMMENT,
+          '''
+/**
+ * [a link split across multiple
+ * lines][c] [b] zzz
+ */
+''',
+          3)
+    ];
+    createParser('');
+    List<CommentReference> references = parser.parseCommentReferences(tokens);
+    expectNotNullIfNoErrors(references);
+    assertNoErrors();
+    expect(references, hasLength(1));
+    CommentReference reference = references[0];
+    expect(reference, isNotNull);
+    expect(reference.identifier, isNotNull);
+    expect(reference.offset, 54);
+  }
+
+  void test_parseCommentReferences_skipLink_reference_singleLine() {
     List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
       new DocumentationCommentToken(
           TokenType.MULTI_LINE_COMMENT, "/** [a][c] [b] zzz */", 3)
@@ -14184,6 +14214,22 @@
     expect(reference.offset, 15);
   }
 
+  void test_parseCommentReferences_skipLinkDefinition() {
+    List<DocumentationCommentToken> tokens = <DocumentationCommentToken>[
+      new DocumentationCommentToken(TokenType.MULTI_LINE_COMMENT,
+          "/** [a]: http://www.google.com (Google) [b] zzz */", 3)
+    ];
+    createParser('');
+    List<CommentReference> references = parser.parseCommentReferences(tokens);
+    expectNotNullIfNoErrors(references);
+    assertNoErrors();
+    expect(references, hasLength(1));
+    CommentReference reference = references[0];
+    expect(reference, isNotNull);
+    expect(reference.identifier, isNotNull);
+    expect(reference.offset, 44);
+  }
+
   void test_parseConfiguration_noOperator_dottedIdentifier() {
     createParser("if (a.b) 'c.dart'");
     Configuration configuration = parser.parseConfiguration();
@@ -18100,24 +18146,6 @@
     expect(alias.semicolon, isNotNull);
   }
 
-  void test_parseGenericTypeAlias_typeParameters_extends_gtGtEq() {
-    // The scanner creates a single token for `>>=`
-    // then the parser must split it into three separate tokens.
-    createParser('typedef F<A,B,C extends D<E>>=Function(A a, B b, C c);');
-    GenericTypeAlias alias = parseFullCompilationUnitMember();
-    expect(alias, isNotNull);
-    assertNoErrors();
-    expect(alias.name, isNotNull);
-    expect(alias.name.name, 'F');
-    expect(alias.typeParameters.typeParameters, hasLength(3));
-    TypeParameter typeParam = alias.typeParameters.typeParameters[2];
-    NamedType type = typeParam.bound;
-    expect(type.typeArguments.arguments, hasLength(1));
-    expect(alias.equals, isNotNull);
-    expect(alias.functionType, isNotNull);
-    expect(alias.semicolon, isNotNull);
-  }
-
   void test_parseGenericTypeAlias_typeParameters_extends3() {
     createParser(
         'typedef F<A,B,C extends D<E,G,H>> = Function(A a, B b, C c);');
@@ -18153,6 +18181,24 @@
     expect(alias.semicolon, isNotNull);
   }
 
+  void test_parseGenericTypeAlias_typeParameters_extends_gtGtEq() {
+    // The scanner creates a single token for `>>=`
+    // then the parser must split it into three separate tokens.
+    createParser('typedef F<A,B,C extends D<E>>=Function(A a, B b, C c);');
+    GenericTypeAlias alias = parseFullCompilationUnitMember();
+    expect(alias, isNotNull);
+    assertNoErrors();
+    expect(alias.name, isNotNull);
+    expect(alias.name.name, 'F');
+    expect(alias.typeParameters.typeParameters, hasLength(3));
+    TypeParameter typeParam = alias.typeParameters.typeParameters[2];
+    NamedType type = typeParam.bound;
+    expect(type.typeArguments.arguments, hasLength(1));
+    expect(alias.equals, isNotNull);
+    expect(alias.functionType, isNotNull);
+    expect(alias.semicolon, isNotNull);
+  }
+
   void test_parseImportDirective_configuration_multiple() {
     createParser("import 'lib/lib.dart' if (a) 'b.dart' if (c) 'd.dart';");
     ImportDirective directive = parseFullDirective();
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index e8b7f00..1898824 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -591,7 +591,7 @@
     Source definingCompilationUnitSource = createNamedSource(fileName);
     List<CompilationUnitElement> sourcedCompilationUnits;
     if (typeNames == null) {
-      sourcedCompilationUnits = CompilationUnitElement.EMPTY_LIST;
+      sourcedCompilationUnits = const <CompilationUnitElement>[];
     } else {
       int count = typeNames.length;
       sourcedCompilationUnits = new List<CompilationUnitElement>(count);
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart
index 1434544..95b7019 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_kernel_test.dart
@@ -294,6 +294,12 @@
 
   @override
   @failingTest
+  test_wrongNumberOfTypeArguments_typeParameter() async {
+    await super.test_wrongNumberOfTypeArguments_typeParameter();
+  }
+
+  @override
+  @failingTest
   test_yield_async_to_basic_type() async {
     await super.test_yield_async_to_basic_type();
   }
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index af2af48..21a69fe 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -2170,6 +2170,18 @@
               ]);
   }
 
+  test_wrongNumberOfTypeArguments_class_tooFew() async {
+    await assertErrorsInCode(r'''
+class A<E, F> {}
+A<A> a = null;''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
+  test_wrongNumberOfTypeArguments_class_tooMany() async {
+    await assertErrorsInCode(r'''
+class A<E> {}
+A<A, A> a = null;''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+  }
+
   test_wrongNumberOfTypeArguments_classAlias() async {
     await assertErrorsInCode(r'''
 class A {}
@@ -2178,16 +2190,18 @@
         [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
   }
 
-  test_wrongNumberOfTypeArguments_tooFew() async {
+  test_wrongNumberOfTypeArguments_dynamic() async {
     await assertErrorsInCode(r'''
-class A<E, F> {}
-A<A> a = null;''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+dynamic<int> v;
+''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
   }
 
-  test_wrongNumberOfTypeArguments_tooMany() async {
+  test_wrongNumberOfTypeArguments_typeParameter() async {
     await assertErrorsInCode(r'''
-class A<E> {}
-A<A, A> a = null;''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
+class C<T> {
+  T<int> f;
+}
+''', [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS]);
   }
 
   test_wrongNumberOfTypeArguments_typeTest_tooFew() async {
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index 279aef0..fbd0736 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -60,8 +60,8 @@
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
     // put values
-    entry.setValue(resultA, 'a', TargetedResult.EMPTY_LIST);
-    entry.setValue(resultB, 'b', TargetedResult.EMPTY_LIST);
+    entry.setValue(resultA, 'a', const <TargetedResult>[]);
+    entry.setValue(resultB, 'b', const <TargetedResult>[]);
     expect(cache.getState(target, resultA), CacheState.VALID);
     expect(cache.getState(target, resultB), CacheState.VALID);
     expect(cache.getValue(target, resultA), 'a');
@@ -184,7 +184,7 @@
     ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
     ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
     // set results, all of them are VALID
-    entry1.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    entry1.setValue(result1, 111, const <TargetedResult>[]);
     entry2.setValue(result2, 222, [new TargetedResult(target1, result1)]);
     entry3.setValue(result3, 333, []);
     expect(entry1.getState(result1), CacheState.VALID);
@@ -208,7 +208,7 @@
     ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
     ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
     // set results, all of them are VALID
-    entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    entry.setValue(result1, 111, const <TargetedResult>[]);
     entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
     expect(entry.getState(result1), CacheState.VALID);
     expect(entry.getState(result2), CacheState.VALID);
@@ -268,7 +268,7 @@
     CacheEntry entry2 = new CacheEntry(target2);
     cache.put(entry1);
     cache.put(entry2);
-    entry1.setValue(descriptor1, 1, TargetedResult.EMPTY_LIST);
+    entry1.setValue(descriptor1, 1, const <TargetedResult>[]);
     entry2.setValue(descriptor2, 2, <TargetedResult>[result1]);
     // target2 is listed as dependent in target1
     expect(
@@ -307,7 +307,7 @@
     CaughtException exception = new CaughtException(null, null);
     entry.setErrorState(exception, <ResultDescriptor>[result]);
     // set the same result to VALID
-    entry.setValue(result, 1, TargetedResult.EMPTY_LIST);
+    entry.setValue(result, 1, const <TargetedResult>[]);
     // fix the exception state
     entry.fixExceptionState();
     expect(entry.exception, isNull);
@@ -329,8 +329,8 @@
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
     // put values
-    entry.setValue(resultA, 'a', TargetedResult.EMPTY_LIST);
-    entry.setValue(resultB, 'b', TargetedResult.EMPTY_LIST);
+    entry.setValue(resultA, 'a', const <TargetedResult>[]);
+    entry.setValue(resultB, 'b', const <TargetedResult>[]);
     expect(entry.getState(resultA), CacheState.VALID);
     expect(entry.getState(resultB), CacheState.VALID);
     expect(entry.getValue(resultA), 'a');
@@ -373,18 +373,18 @@
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
     {
-      entry.setValue(descriptor1, 1, TargetedResult.EMPTY_LIST);
+      entry.setValue(descriptor1, 1, const <TargetedResult>[]);
       expect(entry.getState(descriptor1), CacheState.VALID);
     }
     {
-      entry.setValue(descriptor2, 2, TargetedResult.EMPTY_LIST);
+      entry.setValue(descriptor2, 2, const <TargetedResult>[]);
       expect(entry.getState(descriptor1), CacheState.VALID);
       expect(entry.getState(descriptor2), CacheState.VALID);
     }
     // get descriptor1, so that descriptor2 will be flushed
     entry.getValue(descriptor1);
     {
-      entry.setValue(descriptor3, 3, TargetedResult.EMPTY_LIST);
+      entry.setValue(descriptor3, 3, const <TargetedResult>[]);
       expect(entry.getState(descriptor1), CacheState.VALID);
       expect(entry.getState(descriptor2), CacheState.FLUSHED);
       expect(entry.getState(descriptor3), CacheState.VALID);
@@ -413,7 +413,7 @@
         new ResultDescriptor<String>('test', null);
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
-    entry.setValue(result, 'value', TargetedResult.EMPTY_LIST);
+    entry.setValue(result, 'value', const <TargetedResult>[]);
     entry.invalidateAllInformation();
     expect(entry.getState(result), CacheState.INVALID);
     expect(entry.getValue(result), isNull);
@@ -427,9 +427,9 @@
     // prepare some good state
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
-    entry.setValue(result1, 10, TargetedResult.EMPTY_LIST);
-    entry.setValue(result2, 20, TargetedResult.EMPTY_LIST);
-    entry.setValue(result3, 30, TargetedResult.EMPTY_LIST);
+    entry.setValue(result1, 10, const <TargetedResult>[]);
+    entry.setValue(result2, 20, const <TargetedResult>[]);
+    entry.setValue(result3, 30, const <TargetedResult>[]);
     // set error state
     CaughtException exception = new CaughtException(null, null);
     entry.setErrorState(exception, <ResultDescriptor>[result1, result2]);
@@ -455,7 +455,7 @@
     ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
     ResultDescriptor<int> result4 = new ResultDescriptor<int>('result4', -4);
     // set results, all of them are VALID
-    entry1.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    entry1.setValue(result1, 111, const <TargetedResult>[]);
     entry2.setValue(result2, 222, [new TargetedResult(target1, result1)]);
     entry2.setValue(result3, 333, [new TargetedResult(target2, result2)]);
     entry2.setValue(result4, 444, []);
@@ -515,7 +515,7 @@
     ResultDescriptor<int> result = new ResultDescriptor<int>('test', null);
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
-    entry.setValue(result, 42, TargetedResult.EMPTY_LIST);
+    entry.setValue(result, 42, const <TargetedResult>[]);
     // an invalid state change
     expect(() {
       entry.setState(result, CacheState.ERROR);
@@ -531,7 +531,7 @@
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
     // set VALID
-    entry.setValue(result, 10, TargetedResult.EMPTY_LIST);
+    entry.setValue(result, 10, const <TargetedResult>[]);
     expect(entry.getState(result), CacheState.VALID);
     expect(entry.getValue(result), 10);
     // set FLUSHED
@@ -546,7 +546,7 @@
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
     // set VALID
-    entry.setValue(result, 10, TargetedResult.EMPTY_LIST);
+    entry.setValue(result, 10, const <TargetedResult>[]);
     expect(entry.getState(result), CacheState.VALID);
     expect(entry.getValue(result), 10);
     // set IN_PROCESS
@@ -561,7 +561,7 @@
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
     // set VALID
-    entry.setValue(result, 10, TargetedResult.EMPTY_LIST);
+    entry.setValue(result, 10, const <TargetedResult>[]);
     expect(entry.getState(result), CacheState.VALID);
     expect(entry.getValue(result), 10);
     // listen, expect "result" invalidation event
@@ -620,7 +620,7 @@
     ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
     ResultDescriptor<int> result4 = new ResultDescriptor<int>('result4', -4);
     // set results, all of them are VALID
-    entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    entry.setValue(result1, 111, const <TargetedResult>[]);
     entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
     entry.setValue(result3, 333, [new TargetedResult(target, result2)]);
     entry.setValue(result4, 444, []);
@@ -653,7 +653,7 @@
     cache.put(entry);
     ResultDescriptor<int> result = new ResultDescriptor<int>('result1', -1);
     // set results, all of them are VALID
-    entry.setValue(result, 111, TargetedResult.EMPTY_LIST);
+    entry.setValue(result, 111, const <TargetedResult>[]);
     expect(entry.getState(result), CacheState.VALID);
     expect(entry.getValue(result), 111);
     // invalidate result, keep entry
@@ -672,7 +672,7 @@
     ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
     ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
     // set results, all of them are VALID
-    entry1.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    entry1.setValue(result1, 111, const <TargetedResult>[]);
     entry2.setValue(result2, 222, [new TargetedResult(target1, result1)]);
     entry2.setValue(result3, 333, [new TargetedResult(target2, result2)]);
     expect(entry1.getState(result1), CacheState.VALID);
@@ -695,7 +695,7 @@
     ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
     ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
     // set results, all of them are VALID
-    entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    entry.setValue(result1, 111, const <TargetedResult>[]);
     entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
     entry.setValue(result3, 333, [new TargetedResult(target, result2)]);
     expect(entry.getState(result1), CacheState.VALID);
@@ -743,7 +743,7 @@
     String value = 'value';
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
-    entry.setValue(result, value, TargetedResult.EMPTY_LIST);
+    entry.setValue(result, value, const <TargetedResult>[]);
     expect(entry.getState(result), CacheState.VALID);
     expect(entry.getValue(result), value);
   }
@@ -763,16 +763,16 @@
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
     {
-      entry.setValue(descriptor1, 1, TargetedResult.EMPTY_LIST);
+      entry.setValue(descriptor1, 1, const <TargetedResult>[]);
       expect(entry.getState(descriptor1), CacheState.VALID);
     }
     {
-      entry.setValue(descriptor2, 2, TargetedResult.EMPTY_LIST);
+      entry.setValue(descriptor2, 2, const <TargetedResult>[]);
       expect(entry.getState(descriptor1), CacheState.VALID);
       expect(entry.getState(descriptor2), CacheState.VALID);
     }
     {
-      entry.setValue(descriptor3, 3, TargetedResult.EMPTY_LIST);
+      entry.setValue(descriptor3, 3, const <TargetedResult>[]);
       expect(entry.getState(descriptor1), CacheState.FLUSHED);
       expect(entry.getState(descriptor2), CacheState.VALID);
       expect(entry.getState(descriptor3), CacheState.VALID);
@@ -803,14 +803,14 @@
     cache.put(entry3);
 
     // Set two results.
-    entry1.setValue(descriptor1, 1, TargetedResult.EMPTY_LIST);
-    entry2.setValue(descriptor2, 2, TargetedResult.EMPTY_LIST);
+    entry1.setValue(descriptor1, 1, const <TargetedResult>[]);
+    entry2.setValue(descriptor2, 2, const <TargetedResult>[]);
     expect(entry1.getState(descriptor1), CacheState.VALID);
     expect(entry2.getState(descriptor2), CacheState.VALID);
 
     // Make source1 priority, so result2 is flushed instead.
     context.prioritySources = <Source>[source1];
-    entry3.setValue(descriptor3, 3, TargetedResult.EMPTY_LIST);
+    entry3.setValue(descriptor3, 3, const <TargetedResult>[]);
     expect(entry1.getState(descriptor1), CacheState.VALID);
     expect(entry2.getState(descriptor2), CacheState.FLUSHED);
     expect(entry3.getState(descriptor3), CacheState.VALID);
@@ -823,14 +823,14 @@
     ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
     ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
     // set results, all of them are VALID
-    entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    entry.setValue(result1, 111, const <TargetedResult>[]);
     entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
     expect(entry.getState(result1), CacheState.VALID);
     expect(entry.getState(result2), CacheState.VALID);
     expect(entry.getValue(result1), 111);
     expect(entry.getValue(result2), 222);
     // set result1; result2 is intact
-    entry.setValue(result1, 1111, TargetedResult.EMPTY_LIST);
+    entry.setValue(result1, 1111, const <TargetedResult>[]);
     expect(entry.getState(result1), CacheState.VALID);
     expect(entry.getState(result2), CacheState.VALID);
     expect(entry.getValue(result1), 1111);
@@ -848,7 +848,7 @@
     ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
     // set results, all of them are VALID
     entry2.setValue(result2, 222, [new TargetedResult(target1, result1)]);
-    entry1.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    entry1.setValue(result1, 111, const <TargetedResult>[]);
     expect(entry1.getState(result1), CacheState.VALID);
     expect(entry2.getState(result2), CacheState.VALID);
     expect(entry1.getValue(result1), 111);
@@ -867,7 +867,7 @@
     ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
     ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
     // set results, all of them are VALID
-    entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
+    entry.setValue(result1, 111, const <TargetedResult>[]);
     entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
     entry.setValue(result3, 333, [new TargetedResult(target, result2)]);
     expect(entry.getState(result1), CacheState.VALID);
@@ -901,7 +901,7 @@
     ResultDescriptor<int> result = new ResultDescriptor<int>('test', null);
     CacheEntry entry = new CacheEntry(target);
     cache.put(entry);
-    entry.setValue(result, 42, TargetedResult.EMPTY_LIST);
+    entry.setValue(result, 42, const <TargetedResult>[]);
     expect(entry.toString(), isNotNull);
   }
 }
@@ -1266,7 +1266,7 @@
     CacheEntry entry2 = new CacheEntry(target2);
     partition1.put(entry1);
     partition2.put(entry2);
-    entry1.setValue(descriptor1, 1, TargetedResult.EMPTY_LIST);
+    entry1.setValue(descriptor1, 1, const <TargetedResult>[]);
     entry2.setValue(descriptor2, 2, <TargetedResult>[result1]);
     // target2 is listed as dependent in target1
     expect(
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
index 5b6ae42..1a18218 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_kernel_test.dart
@@ -19,13 +19,6 @@
 
   @override
   @failingTest
-  @FastaProblem('https://github.com/dart-lang/sdk/issues/33795')
-  test_annotation_onDirective_partOf() async {
-    await super.test_annotation_onDirective_partOf();
-  }
-
-  @override
-  @failingTest
   test_generic_function_type() async {
     await super.test_generic_function_type();
   }
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 390a0ca..8624cb8 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -956,6 +956,102 @@
     assertElement(zRef, findElement.parameter('z'));
   }
 
+  test_assign_to_postfix_increment() async {
+    addTestFile('''
+void f(num x, int y) {
+  x++ = y;
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x++');
+    assertType(xRef, 'num');
+    assertElement(xRef, findElement.parameter('x'));
+    var yRef = findNode.simple('y;');
+    assertType(yRef, 'int');
+    assertElement(yRef, findElement.parameter('y'));
+  }
+
+  test_assign_to_postfix_increment_compound() async {
+    addTestFile('''
+void f(num x, int y) {
+  x++ += y;
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x++');
+    assertType(xRef, 'num');
+    assertElement(xRef, findElement.parameter('x'));
+    var yRef = findNode.simple('y;');
+    assertType(yRef, 'int');
+    assertElement(yRef, findElement.parameter('y'));
+  }
+
+  test_assign_to_postfix_increment_null_aware() async {
+    addTestFile('''
+void f(num x, int y) {
+  x++ ??= y;
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x++');
+    assertType(xRef, 'num');
+    assertElement(xRef, findElement.parameter('x'));
+    var yRef = findNode.simple('y;');
+    assertType(yRef, 'int');
+    assertElement(yRef, findElement.parameter('y'));
+  }
+
+  test_assign_to_prefix_increment() async {
+    addTestFile('''
+void f(num x, int y) {
+  ++x = y;
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x =');
+    assertType(xRef, 'num');
+    assertElement(xRef, findElement.parameter('x'));
+    var yRef = findNode.simple('y;');
+    assertType(yRef, 'int');
+    assertElement(yRef, findElement.parameter('y'));
+  }
+
+  test_assign_to_prefix_increment_compound() async {
+    addTestFile('''
+void f(num x, int y) {
+  ++x += y;
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x +=');
+    assertType(xRef, 'num');
+    assertElement(xRef, findElement.parameter('x'));
+    var yRef = findNode.simple('y;');
+    assertType(yRef, 'int');
+    assertElement(yRef, findElement.parameter('y'));
+  }
+
+  test_assign_to_prefix_increment_null_aware() async {
+    addTestFile('''
+void f(num x, int y) {
+  ++x ??= y;
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x ??=');
+    assertType(xRef, 'num');
+    assertElement(xRef, findElement.parameter('x'));
+    var yRef = findNode.simple('y;');
+    assertType(yRef, 'int');
+    assertElement(yRef, findElement.parameter('y'));
+  }
+
   test_assign_with_synthetic_lhs() async {
     addTestFile('''
 void f(int x) {
@@ -969,6 +1065,21 @@
     assertElement(xRef, findElement.parameter('x'));
   }
 
+  test_assign_with_synthetic_lhs_in_method() async {
+    addTestFile('''
+class C {
+  void f(int x) {
+    = x;
+  }
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x;');
+    assertType(xRef, 'int');
+    assertElement(xRef, findElement.parameter('x'));
+  }
+
   test_assignment_to_final_parameter() async {
     addTestFile('''
 f(final int x) {
@@ -2486,7 +2597,6 @@
 main() {
   a.loadLibrary();
 }
-
 ''');
     await resolveTestFile();
     var import = findElement.import('package:test/a.dart');
@@ -2514,7 +2624,6 @@
 main() {
   a.loadLibrary(b, c);
 }
-
 ''');
     await resolveTestFile();
     var import = findElement.import('package:test/a.dart');
@@ -2548,7 +2657,6 @@
 main() {
   a.loadLibrary;
 }
-
 ''');
     await resolveTestFile();
     var import = findElement.import('package:test/a.dart');
@@ -2574,7 +2682,6 @@
   a.v;
   a.v = 1;
 }
-
 ''');
     await resolveTestFile();
     var import = findElement.import('package:test/a.dart');
@@ -2607,6 +2714,153 @@
     }
   }
 
+  test_directive_export() async {
+    var a = _p('/test/lib/a.dart');
+    provider.newFile(a, r'''
+class MyClass {}
+int myVar;
+int get myGetter => 0;
+int set mySetter(_) {}
+''');
+    addTestFile(r'''
+export 'a.dart' show MyClass, myVar, myGetter, mySetter, Unresolved;
+''');
+    await resolveTestFile();
+    var export = findElement.export('package:test/a.dart');
+    var namespace = export.exportedLibrary.exportNamespace;
+
+    {
+      var ref = findNode.simple('MyClass');
+      assertElement(ref, namespace.get('MyClass'));
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('myVar');
+      PropertyAccessorElement getter = namespace.get('myVar');
+      assertElement(ref, getter.variable);
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('myGetter');
+      PropertyAccessorElement getter = namespace.get('myGetter');
+      assertElement(ref, getter.variable);
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('mySetter');
+      PropertyAccessorElement getter = namespace.get('mySetter=');
+      assertElement(ref, getter.variable);
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('Unresolved');
+      assertElementNull(ref);
+      assertType(ref, null);
+    }
+  }
+
+  test_directive_import_hide() async {
+    var a = _p('/test/lib/a.dart');
+    provider.newFile(a, r'''
+class MyClass {}
+int myVar;
+int get myGetter => 0;
+int set mySetter(_) {}
+''');
+    addTestFile(r'''
+import 'a.dart' hide MyClass, myVar, myGetter, mySetter, Unresolved;
+''');
+    await resolveTestFile();
+    var import = findElement.import('package:test/a.dart');
+    var namespace = import.importedLibrary.exportNamespace;
+
+    {
+      var ref = findNode.simple('MyClass');
+      assertElement(ref, namespace.get('MyClass'));
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('myVar');
+      PropertyAccessorElement getter = namespace.get('myVar');
+      assertElement(ref, getter.variable);
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('myGetter');
+      PropertyAccessorElement getter = namespace.get('myGetter');
+      assertElement(ref, getter.variable);
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('mySetter');
+      PropertyAccessorElement getter = namespace.get('mySetter=');
+      assertElement(ref, getter.variable);
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('Unresolved');
+      assertElementNull(ref);
+      assertType(ref, null);
+    }
+  }
+
+  test_directive_import_show() async {
+    var a = _p('/test/lib/a.dart');
+    provider.newFile(a, r'''
+class MyClass {}
+int myVar;
+int get myGetter => 0;
+int set mySetter(_) {}
+''');
+    addTestFile(r'''
+import 'a.dart' show MyClass, myVar, myGetter, mySetter, Unresolved;
+''');
+    await resolveTestFile();
+    var import = findElement.import('package:test/a.dart');
+    var namespace = import.importedLibrary.exportNamespace;
+
+    {
+      var ref = findNode.simple('MyClass');
+      assertElement(ref, namespace.get('MyClass'));
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('myVar');
+      PropertyAccessorElement getter = namespace.get('myVar');
+      assertElement(ref, getter.variable);
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('myGetter');
+      PropertyAccessorElement getter = namespace.get('myGetter');
+      assertElement(ref, getter.variable);
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('mySetter');
+      PropertyAccessorElement getter = namespace.get('mySetter=');
+      assertElement(ref, getter.variable);
+      assertType(ref, null);
+    }
+
+    {
+      var ref = findNode.simple('Unresolved');
+      assertElementNull(ref);
+      assertType(ref, null);
+    }
+  }
+
   test_enum_toString() async {
     addTestFile(r'''
 enum MyEnum { A, B, C }
@@ -4387,6 +4641,21 @@
     assertIdentifierTopGetRef(arg2.expression, 'c');
   }
 
+  test_invalid_invocation_arguments_requiredAfterNamed() async {
+    addTestFile(r'''
+var a = 0;
+var b = 0;
+main() {
+  f(p: a, b);
+}
+void f({p}) {}
+''');
+    await resolveTestFile();
+    expect(result.errors, isNotEmpty);
+    assertTopGetRef('a, ', 'a');
+    assertTopGetRef('b);', 'b');
+  }
+
   test_invalid_invocation_arguments_static_method() async {
     addTestFile(r'''
 class C {
@@ -7149,6 +7418,32 @@
         expectedPrefix: myImport.prefix);
   }
 
+  test_postfix_increment_of_non_generator() async {
+    addTestFile('''
+void f(int g()) {
+  g()++;
+}
+''');
+    await resolveTestFile();
+
+    var gRef = findNode.simple('g()++');
+    assertType(gRef, '() → int');
+    assertElement(gRef, findElement.parameter('g'));
+  }
+
+  test_postfix_increment_of_postfix_increment() async {
+    addTestFile('''
+void f(int x) {
+  x ++ ++;
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x ++');
+    assertType(xRef, 'int');
+    assertElement(xRef, findElement.parameter('x'));
+  }
+
   test_postfixExpression_local() async {
     String content = r'''
 main() {
@@ -7223,6 +7518,45 @@
     }
   }
 
+  test_prefix_increment_of_non_generator() async {
+    addTestFile('''
+void f(bool x) {
+  ++!x;
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x;');
+    assertType(xRef, 'bool');
+    assertElement(xRef, findElement.parameter('x'));
+  }
+
+  test_prefix_increment_of_postfix_increment() async {
+    addTestFile('''
+void f(int x) {
+  ++x++;
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x++');
+    assertType(xRef, 'int');
+    assertElement(xRef, findElement.parameter('x'));
+  }
+
+  test_prefix_increment_of_prefix_increment() async {
+    addTestFile('''
+void f(int x) {
+  ++ ++ x;
+}
+''');
+    await resolveTestFile();
+
+    var xRef = findNode.simple('x;');
+    assertType(xRef, 'int');
+    assertElement(xRef, findElement.parameter('x'));
+  }
+
   test_prefixedIdentifier_classInstance_instanceField() async {
     String content = r'''
 main() {
@@ -10241,6 +10575,23 @@
     fail('Not found class: $name');
   }
 
+  ExportElement export(String targetUri) {
+    ExportElement exportElement;
+    for (var export in unitElement.library.exports) {
+      var exportedUri = export.exportedLibrary.source.uri.toString();
+      if (exportedUri == targetUri) {
+        if (exportElement != null) {
+          throw new StateError('Not unique $targetUri export.');
+        }
+        exportElement = export;
+      }
+    }
+    if (exportElement != null) {
+      return exportElement;
+    }
+    fail('Not found export: $targetUri');
+  }
+
   FieldElement field(String name) {
     for (var type in unitElement.types) {
       for (var field in type.fields) {
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index 7a7e093..53e073e 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -1994,11 +1994,6 @@
 
   @failingTest
   @override
-  test_searchReferences_TopLevelVariableElement() =>
-      super.test_searchReferences_TopLevelVariableElement();
-
-  @failingTest
-  @override
   test_subtypes_partWithoutLibrary() =>
       super.test_subtypes_partWithoutLibrary();
 }
diff --git a/pkg/analyzer/test/src/dart/constant/utilities_test.dart b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
index 13a0ed1..3a195fb 100644
--- a/pkg/analyzer/test/src/dart/constant/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
@@ -252,7 +252,7 @@
       constructorDeclaration.element = constructorElement;
       classElement.constructors = <ConstructorElement>[constructorElement];
     } else {
-      classElement.constructors = ConstructorElement.EMPTY_LIST;
+      classElement.constructors = const <ConstructorElement>[];
     }
     return variableDeclaration;
   }
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index ccce9b5..3d02cda 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -1942,12 +1942,12 @@
   }
 
   DartObjectImpl _listValue(
-      [List<DartObjectImpl> elements = DartObjectImpl.EMPTY_LIST]) {
+      [List<DartObjectImpl> elements = const <DartObjectImpl>[]]) {
     return new DartObjectImpl(_typeProvider.listType, new ListState(elements));
   }
 
   DartObjectImpl _mapValue(
-      [List<DartObjectImpl> keyElementPairs = DartObjectImpl.EMPTY_LIST]) {
+      [List<DartObjectImpl> keyElementPairs = const <DartObjectImpl>[]]) {
     Map<DartObjectImpl, DartObjectImpl> map =
         new Map<DartObjectImpl, DartObjectImpl>();
     int count = keyElementPairs.length;
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index a47767a..45e17dcb 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -2534,7 +2534,7 @@
 
   void test_getConstructors_empty() {
     ClassElementImpl typeElement = ElementFactory.classElement2("A");
-    typeElement.constructors = ConstructorElement.EMPTY_LIST;
+    typeElement.constructors = const <ConstructorElement>[];
     InterfaceTypeImpl type = new InterfaceTypeImpl(typeElement);
     expect(type.constructors, isEmpty);
   }
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
index 195c480..9cdd293 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
@@ -42,9 +42,6 @@
   bool get skipFullyLinkedData => false;
 
   @override
-  bool get skipNonConstInitializers => false;
-
-  @override
   void serializeLibraryText(String text, {bool allowErrors: false}) {
     Map<String, UnlinkedUnitBuilder> uriToUnit = this._filesToLink.uriToUnit;
     linkerInputs = createLinkerInputs(text);
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 0044bc0..980639d 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -138,13 +138,6 @@
   LinkedUnit get definingUnit => linked.units[0];
 
   /**
-   * Whether the parts of the IDL marked `@informative` are expected to be
-   * included in the generated summary; if `false`, these parts of the IDL won't
-   * be checked.
-   */
-  bool get includeInformative => true;
-
-  /**
    * Get access to the linked summary that results from serializing and
    * then deserializing the library under test.
    */
@@ -157,11 +150,6 @@
   bool get skipFullyLinkedData;
 
   /**
-   * `true` if non-const variable initializers are not serialized.
-   */
-  bool get skipNonConstInitializers;
-
-  /**
    * Get access to the unlinked compilation unit summaries that result from
    * serializing and deserializing the library under test.
    */
@@ -1128,7 +1116,6 @@
   }
 
   test_class_alias_documented() {
-    if (!includeInformative) return;
     String text = '''
 // Extra comment so doc comment offset != 0
 /**
@@ -1206,7 +1193,6 @@
   }
 
   test_class_codeRange() {
-    if (!includeInformative) return;
     UnlinkedClass cls = serializeClassText(' class C {}');
     _assertCodeRange(cls.codeRange, 1, 10);
   }
@@ -1295,7 +1281,6 @@
   }
 
   test_class_documented() {
-    if (!includeInformative) return;
     String text = '''
 // Extra comment so doc comment offset != 0
 /**
@@ -1308,7 +1293,6 @@
   }
 
   test_class_documented_tripleSlash() {
-    if (!includeInformative) return;
     String text = '''
 /// aaa
 /// bbbb
@@ -1321,7 +1305,6 @@
   }
 
   test_class_documented_with_references() {
-    if (!includeInformative) return;
     String text = '''
 // Extra comment so doc comment offset != 0
 /**
@@ -1337,7 +1320,6 @@
   }
 
   test_class_documented_with_with_windows_line_endings() {
-    if (!includeInformative) return;
     String text = '/**\r\n * Docs\r\n */\r\nclass C {}';
     UnlinkedClass cls = serializeClassText(text);
     expect(cls.documentationComment, isNotNull);
@@ -1388,9 +1370,7 @@
     var classText = 'class C {}';
     UnlinkedClass cls = serializeClassText(classText);
     expect(cls.name, 'C');
-    if (includeInformative) {
-      expect(cls.nameOffset, classText.indexOf('C'));
-    }
+    expect(cls.nameOffset, classText.indexOf('C'));
   }
 
   test_class_no_flags() {
@@ -1479,9 +1459,7 @@
     UnlinkedClass cls = serializeClassText(text);
     expect(cls.typeParameters, hasLength(1));
     expect(cls.typeParameters[0].name, 'T');
-    if (includeInformative) {
-      expect(cls.typeParameters[0].nameOffset, text.indexOf('T'));
-    }
+    expect(cls.typeParameters[0].nameOffset, text.indexOf('T'));
     expect(cls.typeParameters[0].bound, isNull);
     expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
   }
@@ -1868,9 +1846,6 @@
   }
 
   test_constExpr_functionExpression() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 import 'dart:async';
 const v = (f) async => await f;
@@ -3489,19 +3464,14 @@
     expect(executable.isAsynchronous, isFalse);
     expect(executable.isExternal, isFalse);
     expect(executable.isGenerator, isFalse);
-    if (includeInformative) {
-      expect(executable.nameOffset, text.indexOf('C();'));
-      expect(executable.periodOffset, 0);
-      expect(executable.nameEnd, 0);
-    }
+    expect(executable.nameOffset, text.indexOf('C();'));
+    expect(executable.periodOffset, 0);
+    expect(executable.nameEnd, 0);
     expect(executable.isRedirectedConstructor, isFalse);
     expect(executable.redirectedConstructor, isNull);
     expect(executable.redirectedConstructorName, isEmpty);
-
-    if (includeInformative) {
-      expect(executable.visibleOffset, 0);
-      expect(executable.visibleLength, 0);
-    }
+    expect(executable.visibleOffset, 0);
+    expect(executable.visibleLength, 0);
   }
 
   test_constructor_anonymous() {
@@ -3526,7 +3496,6 @@
   }
 
   test_constructor_documented() {
-    if (!includeInformative) return;
     String text = '''
 class C {
   /**
@@ -3927,9 +3896,7 @@
     expect(parameter.kind, UnlinkedParamKind.named);
     expect(parameter.initializer, isNotNull);
     expect(parameter.defaultValueCode, '42');
-    if (includeInformative) {
-      _assertCodeRange(parameter.codeRange, 13, 10);
-    }
+    _assertCodeRange(parameter.codeRange, 13, 10);
     assertUnlinkedConst(parameter.initializer.bodyExpr,
         operators: [UnlinkedExprOperation.pushInt], ints: [42]);
   }
@@ -3961,9 +3928,7 @@
     expect(parameter.kind, UnlinkedParamKind.positional);
     expect(parameter.initializer, isNotNull);
     expect(parameter.defaultValueCode, '42');
-    if (includeInformative) {
-      _assertCodeRange(parameter.codeRange, 13, 11);
-    }
+    _assertCodeRange(parameter.codeRange, 13, 11);
     assertUnlinkedConst(parameter.initializer.bodyExpr,
         operators: [UnlinkedExprOperation.pushInt], ints: [42]);
   }
@@ -4005,12 +3970,10 @@
     UnlinkedExecutable executable = findExecutable('foo',
         executables: serializeClassText(text).executables);
     expect(executable.name, 'foo');
-    if (includeInformative) {
-      expect(executable.nameOffset, text.indexOf('foo'));
-      expect(executable.periodOffset, text.indexOf('.foo'));
-      expect(executable.nameEnd, text.indexOf('()'));
-      _assertCodeRange(executable.codeRange, 10, 8);
-    }
+    expect(executable.nameOffset, text.indexOf('foo'));
+    expect(executable.periodOffset, text.indexOf('.foo'));
+    expect(executable.nameEnd, text.indexOf('()'));
+    _assertCodeRange(executable.codeRange, 10, 8);
   }
 
   test_constructor_non_const() {
@@ -5051,15 +5014,11 @@
     String text = 'enum E { v1 }';
     UnlinkedEnum e = serializeEnumText(text);
     expect(e.name, 'E');
-    if (includeInformative) {
-      expect(e.nameOffset, text.indexOf('E'));
-    }
+    expect(e.nameOffset, text.indexOf('E'));
     expect(e.values, hasLength(1));
     expect(e.values[0].name, 'v1');
-    if (includeInformative) {
-      expect(e.values[0].nameOffset, text.indexOf('v1'));
-      _assertCodeRange(e.codeRange, 0, 13);
-    }
+    expect(e.values[0].nameOffset, text.indexOf('v1'));
+    _assertCodeRange(e.codeRange, 0, 13);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
     expect(unlinkedUnits[0].publicNamespace.names[0].kind,
         ReferenceKind.classOrEnum);
@@ -5081,7 +5040,6 @@
   }
 
   test_enum_documented() {
-    if (!includeInformative) return;
     String text = '''
 // Extra comment so doc comment offset != 0
 /**
@@ -5106,7 +5064,6 @@
   }
 
   test_enum_value_documented() {
-    if (!includeInformative) return;
     String text = '''
 enum E {
   /**
@@ -5146,11 +5103,9 @@
     expect(executable.isAsynchronous, isFalse);
     expect(executable.isExternal, isFalse);
     expect(executable.isGenerator, isFalse);
-    if (includeInformative) {
-      expect(executable.nameOffset, text.indexOf('f'));
-      expect(executable.visibleOffset, 0);
-      expect(executable.visibleLength, 0);
-    }
+    expect(executable.nameOffset, text.indexOf('f'));
+    expect(executable.visibleOffset, 0);
+    expect(executable.visibleLength, 0);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
     expect(unlinkedUnits[0].publicNamespace.names[0].kind,
         ReferenceKind.topLevelFunction);
@@ -5200,9 +5155,7 @@
     expect(executable.isAsynchronous, isFalse);
     expect(executable.isExternal, isFalse);
     expect(executable.isGenerator, isFalse);
-    if (includeInformative) {
-      expect(executable.nameOffset, text.indexOf('f'));
-    }
+    expect(executable.nameOffset, text.indexOf('f'));
     expect(findVariable('f'), isNull);
     expect(findExecutable('f='), isNull);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
@@ -5256,11 +5209,9 @@
     expect(executable.isAsynchronous, isFalse);
     expect(executable.isExternal, isFalse);
     expect(executable.isGenerator, isFalse);
-    if (includeInformative) {
-      expect(executable.visibleOffset, 0);
-      expect(executable.visibleLength, 0);
-      _assertCodeRange(executable.codeRange, 10, 6);
-    }
+    expect(executable.visibleOffset, 0);
+    expect(executable.visibleLength, 0);
+    _assertCodeRange(executable.codeRange, 10, 6);
   }
 
   test_executable_member_function_async() {
@@ -5311,9 +5262,7 @@
     expect(executable.isExternal, isFalse);
     expect(executable.isGenerator, isFalse);
     expect(executable.isStatic, isFalse);
-    if (includeInformative) {
-      _assertCodeRange(executable.codeRange, 10, 15);
-    }
+    _assertCodeRange(executable.codeRange, 10, 15);
     expect(findVariable('f', variables: cls.fields), isNull);
     expect(findExecutable('f=', executables: cls.executables), isNull);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
@@ -5356,9 +5305,7 @@
     expect(executable.isAsynchronous, isFalse);
     expect(executable.isExternal, isFalse);
     expect(executable.isGenerator, isFalse);
-    if (includeInformative) {
-      _assertCodeRange(executable.codeRange, 10, 20);
-    }
+    _assertCodeRange(executable.codeRange, 10, 20);
     expect(findVariable('f', variables: cls.fields), isNull);
     expect(findExecutable('f', executables: cls.executables), isNull);
   }
@@ -5496,7 +5443,6 @@
   }
 
   test_executable_param_codeRange() {
-    if (!includeInformative) return;
     UnlinkedExecutable executable = serializeExecutableText('f(int x) {}');
     UnlinkedParam parameter = executable.parameters[0];
     _assertCodeRange(parameter.codeRange, 2, 5);
@@ -5588,9 +5534,7 @@
     expect(param.kind, UnlinkedParamKind.named);
     expect(param.initializer, isNotNull);
     expect(param.defaultValueCode, '42');
-    if (includeInformative) {
-      _assertCodeRange(param.codeRange, 3, 5);
-    }
+    _assertCodeRange(param.codeRange, 3, 5);
     assertUnlinkedConst(param.initializer.bodyExpr,
         operators: [UnlinkedExprOperation.pushInt], ints: [42]);
   }
@@ -5609,9 +5553,7 @@
     expect(param.kind, UnlinkedParamKind.positional);
     expect(param.initializer, isNotNull);
     expect(param.defaultValueCode, '42');
-    if (includeInformative) {
-      _assertCodeRange(param.codeRange, 3, 6);
-    }
+    _assertCodeRange(param.codeRange, 3, 6);
     assertUnlinkedConst(param.initializer.bodyExpr,
         operators: [UnlinkedExprOperation.pushInt], ints: [42]);
   }
@@ -5629,9 +5571,7 @@
     UnlinkedExecutable executable = serializeExecutableText(text);
     expect(executable.parameters, hasLength(1));
     expect(executable.parameters[0].name, 'x');
-    if (includeInformative) {
-      expect(executable.parameters[0].nameOffset, text.indexOf('x'));
-    }
+    expect(executable.parameters[0].nameOffset, text.indexOf('x'));
   }
 
   test_executable_param_no_flags() {
@@ -5736,9 +5676,7 @@
     expect(executable.isAsynchronous, isFalse);
     expect(executable.isExternal, isFalse);
     expect(executable.isGenerator, isFalse);
-    if (includeInformative) {
-      expect(executable.nameOffset, text.indexOf('f'));
-    }
+    expect(executable.nameOffset, text.indexOf('f'));
     expect(findVariable('f'), isNull);
     expect(findExecutable('f'), isNull);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
@@ -5936,11 +5874,9 @@
         'Future');
     expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[1],
         'Stream');
-    if (includeInformative) {
-      expect(
-          unlinkedUnits[0].publicNamespace.exports[0].combinators[0].offset, 0);
-      expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].end, 0);
-    }
+    expect(
+        unlinkedUnits[0].publicNamespace.exports[0].combinators[0].offset, 0);
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].end, 0);
     expect(linked.exportNames, isNotEmpty);
   }
 
@@ -6055,12 +5991,10 @@
         'Future');
     expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[1],
         'Stream');
-    if (includeInformative) {
-      expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].offset,
-          libraryText.indexOf('show'));
-      expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].end,
-          libraryText.indexOf(';'));
-    }
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].offset,
+        libraryText.indexOf('show'));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].end,
+        libraryText.indexOf(';'));
   }
 
   test_export_typedef() {
@@ -6191,9 +6125,6 @@
   }
 
   test_expr_assignToIndex_ofFieldSequence() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class A {
   B b;
@@ -6236,9 +6167,6 @@
   }
 
   test_expr_assignToIndex_ofIndexExpression() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class A {
  List<B> b;
@@ -6294,9 +6222,6 @@
   }
 
   test_expr_assignToIndex_ofTopLevelVariable() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 List<int> a = <int>[0, 1, 2];
 final v = (a[1] = 5);
@@ -6324,9 +6249,6 @@
   }
 
   test_expr_assignToProperty_ofInstanceCreation() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class C {
   int f;
@@ -6358,9 +6280,6 @@
   }
 
   test_expr_assignToRef_classStaticField() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class C {
   static int f;
@@ -6390,9 +6309,6 @@
   }
 
   test_expr_assignToRef_fieldSequence() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class A {
   B b;
@@ -6452,9 +6368,6 @@
   }
 
   test_expr_assignToRef_topLevelVariable() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 int a = 0;
 final v = (a = 1);
@@ -6479,9 +6392,6 @@
   }
 
   test_expr_assignToRef_topLevelVariable_imported() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     addNamedSource('/a.dart', '''
 int a = 0;
 ''');
@@ -6509,9 +6419,6 @@
   }
 
   test_expr_assignToRef_topLevelVariable_imported_withPrefix() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     addNamedSource('/a.dart', '''
 int a = 0;
 ''');
@@ -6542,9 +6449,6 @@
   }
 
   test_expr_cascadeSection_assignToIndex() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class C {
   List<int> items;
@@ -6571,9 +6475,6 @@
   }
 
   test_expr_cascadeSection_assignToProperty() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class C {
   int f1 = 0;
@@ -6599,9 +6500,6 @@
   }
 
   test_expr_cascadeSection_embedded() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class A {
   int fa1;
@@ -6634,9 +6532,6 @@
   }
 
   test_expr_cascadeSection_invokeMethod() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class A {
   int m(int _) => 0;
@@ -6658,9 +6553,6 @@
   }
 
   test_expr_extractIndex_ofClassField() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class C {
   List<int> get items => null;
@@ -6690,9 +6582,6 @@
   }
 
   test_expr_extractProperty_ofInvokeConstructor() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class C {
   int f = 0;
@@ -6774,9 +6663,6 @@
   }
 
   test_expr_functionExpression_withBlockBody() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 final v = () { return 42; };
 ''');
@@ -6787,9 +6673,6 @@
   }
 
   test_expr_functionExpression_withExpressionBody() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 final v = () => 42;
 ''');
@@ -6800,9 +6683,6 @@
   }
 
   test_expr_functionExpressionInvocation_withBlockBody() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 final v = ((a, b) {return 42;})(1, 2);
 ''');
@@ -6811,9 +6691,6 @@
   }
 
   test_expr_functionExpressionInvocation_withExpressionBody() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 final v = ((a, b) => 42)(1, 2);
 ''');
@@ -6822,9 +6699,6 @@
   }
 
   test_expr_inClosure() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('var v = () => 1;');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
         operators: [UnlinkedExprOperation.pushInt], ints: [1]);
@@ -6838,9 +6712,6 @@
   }
 
   test_expr_inClosure_refersToOuterParam() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable =
         serializeVariableText('var v = (x) => (y) => x;');
     assertUnlinkedConst(
@@ -6850,18 +6721,12 @@
   }
 
   test_expr_inClosure_refersToParam() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('var v = (x) => x;');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
         operators: [UnlinkedExprOperation.pushParameter], strings: ['x']);
   }
 
   test_expr_inClosure_refersToParam_methodCall() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('var v = (x) => x.f();');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
         operators: [
@@ -6880,9 +6745,6 @@
   }
 
   test_expr_inClosure_refersToParam_methodCall_prefixed() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable =
         serializeVariableText('var v = (x) => x.y.f();');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
@@ -6904,9 +6766,6 @@
   }
 
   test_expr_inClosure_refersToParam_outOfScope() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable =
         serializeVariableText('var x; var v = (b) => (b ? (x) => x : x);');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
@@ -6931,9 +6790,6 @@
   }
 
   test_expr_inClosure_refersToParam_prefixedIdentifier() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('var v = (x) => x.y;');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
         operators: [
@@ -6947,9 +6803,6 @@
   }
 
   test_expr_inClosure_refersToParam_prefixedIdentifier_assign() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable =
         serializeVariableText('var v = (x) => x.y = null;');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
@@ -6969,9 +6822,6 @@
   }
 
   test_expr_inClosure_refersToParam_prefixedPrefixedIdentifier() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('var v = (x) => x.y.z;');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
         operators: [
@@ -6987,9 +6837,6 @@
   }
 
   test_expr_inClosure_refersToParam_prefixedPrefixedIdentifier_assign() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable =
         serializeVariableText('var v = (x) => x.y.z = null;');
     assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr,
@@ -7011,9 +6858,6 @@
   }
 
   test_expr_invalid_typeParameter_asPrefix() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     var c = serializeClassText('''
 class C<T> {
   final f = T.k;
@@ -7061,9 +6905,6 @@
   }
 
   test_expr_invokeMethod_withTypeParameters() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class C {
   f<T, U>() => null;
@@ -7094,9 +6935,6 @@
   }
 
   test_expr_invokeMethodRef_instance() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 class A {
   B b;
@@ -7133,9 +6971,6 @@
   }
 
   test_expr_invokeMethodRef_static_importedWithPrefix() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     addNamedSource('/a.dart', '''
 class C {
   static int m() => 42;
@@ -7163,9 +6998,6 @@
   }
 
   test_expr_invokeMethodRef_with_reference_arg() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 f(x) => null;
 final u = null;
@@ -7187,9 +7019,6 @@
   }
 
   test_expr_invokeMethodRef_withTypeParameters() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 f<T, U>() => null;
 final v = f<int, String>();
@@ -7275,9 +7104,6 @@
   }
 
   test_expr_super() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 final v = super;
 ''');
@@ -7287,9 +7113,6 @@
   }
 
   test_expr_this() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 final v = this;
 ''');
@@ -7299,9 +7122,6 @@
   }
 
   test_expr_throwException() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 final v = throw 1 + 2;
 ''');
@@ -7320,9 +7140,6 @@
   }
 
   test_expr_typeCast() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 final v = 42 as num;
 ''');
@@ -7342,9 +7159,6 @@
   }
 
   test_expr_typeCheck() {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 final v = 42 is num;
 ''');
@@ -7389,7 +7203,6 @@
   }
 
   test_field_documented() {
-    if (!includeInformative) return;
     String text = '''
 class C {
   /**
@@ -7578,7 +7391,6 @@
   }
 
   test_function_documented() {
-    if (!includeInformative) return;
     String text = '''
 // Extra comment so doc comment offset != 0
 /**
@@ -7611,7 +7423,6 @@
   }
 
   test_getter_documented() {
-    if (!includeInformative) return;
     String text = '''
 // Extra comment so doc comment offset != 0
 /**
@@ -7720,10 +7531,8 @@
     expect(unlinkedUnits[0].imports[0].combinators[0].hides, hasLength(2));
     expect(unlinkedUnits[0].imports[0].combinators[0].hides[0], 'Future');
     expect(unlinkedUnits[0].imports[0].combinators[0].hides[1], 'Stream');
-    if (includeInformative) {
-      expect(unlinkedUnits[0].imports[0].combinators[0].offset, 0);
-      expect(unlinkedUnits[0].imports[0].combinators[0].end, 0);
-    }
+    expect(unlinkedUnits[0].imports[0].combinators[0].offset, 0);
+    expect(unlinkedUnits[0].imports[0].combinators[0].end, 0);
   }
 
   test_import_implicit() {
@@ -7732,10 +7541,8 @@
     expect(unlinkedUnits[0].imports, hasLength(1));
     checkDependency(linked.importDependencies[0], 'dart:core');
     expect(unlinkedUnits[0].imports[0].uri, isEmpty);
-    if (includeInformative) {
-      expect(unlinkedUnits[0].imports[0].uriOffset, 0);
-      expect(unlinkedUnits[0].imports[0].uriEnd, 0);
-    }
+    expect(unlinkedUnits[0].imports[0].uriOffset, 0);
+    expect(unlinkedUnits[0].imports[0].uriEnd, 0);
     expect(unlinkedUnits[0].imports[0].prefixReference, 0);
     expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
     expect(unlinkedUnits[0].imports[0].isImplicit, isTrue);
@@ -8317,7 +8124,6 @@
   }
 
   test_library_documented() {
-    if (!includeInformative) return;
     String text = '''
 // Extra comment so doc comment offset != 0
 /**
@@ -8926,7 +8732,6 @@
   }
 
   test_method_documented() {
-    if (!includeInformative) return;
     String text = '''
 class C {
   /**
@@ -9162,7 +8967,6 @@
   }
 
   test_setter_documented() {
-    if (!includeInformative) return;
     String text = '''
 // Extra comment so doc comment offset != 0
 /**
@@ -9386,7 +9190,6 @@
   }
 
   test_type_param_codeRange() {
-    if (!includeInformative) return;
     UnlinkedClass cls =
         serializeClassText('class A {} class C<T extends A> {}');
     UnlinkedTypeParam typeParameter = cls.typeParameters[0];
@@ -9631,13 +9434,11 @@
   }
 
   test_typedef_codeRange() {
-    if (!includeInformative) return;
     UnlinkedTypedef type = serializeTypedefText('typedef F();');
     _assertCodeRange(type.codeRange, 0, 12);
   }
 
   test_typedef_documented() {
-    if (!includeInformative) return;
     String text = '''
 // Extra comment so doc comment offset != 0
 /**
@@ -9707,9 +9508,7 @@
     String text = 'typedef F();';
     UnlinkedTypedef type = serializeTypedefText(text);
     expect(type.name, 'F');
-    if (includeInformative) {
-      expect(type.nameOffset, text.indexOf('F'));
-    }
+    expect(type.nameOffset, text.indexOf('F'));
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
     expect(
         unlinkedUnits[0].publicNamespace.names[0].kind, ReferenceKind.typedef);
@@ -9778,7 +9577,6 @@
   }
 
   test_unit_codeRange() {
-    if (!includeInformative) return;
     serializeLibraryText('  int a = 1;  ');
     UnlinkedUnit unit = unlinkedUnits[0];
     _assertCodeRange(unit.codeRange, 0, 14);
@@ -9855,9 +9653,7 @@
   test_variable() {
     String text = 'int i;';
     UnlinkedVariable v = serializeVariableText(text, variableName: 'i');
-    if (includeInformative) {
-      expect(v.nameOffset, text.indexOf('i;'));
-    }
+    expect(v.nameOffset, text.indexOf('i;'));
     expect(findExecutable('i'), isNull);
     expect(findExecutable('i='), isNull);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
@@ -9872,7 +9668,6 @@
   }
 
   test_variable_codeRange() {
-    if (!includeInformative) return;
     serializeLibraryText(' int a = 1, b = 22;');
     List<UnlinkedVariable> variables = unlinkedUnits[0].variables;
     _assertCodeRange(variables[0].codeRange, 1, 9);
@@ -9886,7 +9681,6 @@
   }
 
   test_variable_documented() {
-    if (!includeInformative) return;
     String text = '''
 // Extra comment so doc comment offset != 0
 /**
@@ -9939,9 +9733,7 @@
     UnlinkedVariable variable = serializeVariableText('var v = 42;');
     UnlinkedExecutable initializer = variable.initializer;
     expect(initializer, isNotNull);
-    if (includeInformative) {
-      expect(initializer.nameOffset, 8);
-    }
+    expect(initializer.nameOffset, 8);
     expect(initializer.name, isEmpty);
     expect(initializer.localFunctions, isEmpty);
   }
@@ -9957,38 +9749,28 @@
     UnlinkedVariable variable = serializeVariableText(text);
     UnlinkedExecutable initializer = variable.initializer;
     expect(initializer, isNotNull);
-    if (includeInformative) {
-      expect(initializer.nameOffset, text.indexOf('<dynamic, dynamic>{"1'));
-    }
+    expect(initializer.nameOffset, text.indexOf('<dynamic, dynamic>{"1'));
     expect(initializer.name, isEmpty);
     expect(initializer.localFunctions, hasLength(2));
     // closure: () { f1() {} var v1; }
     {
       UnlinkedExecutable closure = initializer.localFunctions[0];
-      if (includeInformative) {
-        expect(closure.nameOffset, text.indexOf('() { f1()'));
-      }
+      expect(closure.nameOffset, text.indexOf('() { f1()'));
       expect(closure.name, isEmpty);
       // closure - f1
       expect(closure.localFunctions, hasLength(1));
       expect(closure.localFunctions[0].name, 'f1');
-      if (includeInformative) {
-        expect(closure.localFunctions[0].nameOffset, text.indexOf('f1()'));
-      }
+      expect(closure.localFunctions[0].nameOffset, text.indexOf('f1()'));
     }
     // closure: () { f2() {} var v2; }
     {
       UnlinkedExecutable closure = initializer.localFunctions[1];
-      if (includeInformative) {
-        expect(closure.nameOffset, text.indexOf('() { f2()'));
-      }
+      expect(closure.nameOffset, text.indexOf('() { f2()'));
       expect(closure.name, isEmpty);
       // closure - f1
       expect(closure.localFunctions, hasLength(1));
       expect(closure.localFunctions[0].name, 'f2');
-      if (includeInformative) {
-        expect(closure.localFunctions[0].nameOffset, text.indexOf('f2()'));
-      }
+      expect(closure.localFunctions[0].nameOffset, text.indexOf('f2()'));
     }
   }
 
@@ -10090,9 +9872,6 @@
    */
   void _assertAssignmentOperator(
       String expr, UnlinkedExprAssignOperator expectedAssignOperator) {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 int a = 0;
 final v = $expr;
@@ -10148,9 +9927,6 @@
    */
   void _assertRefPrefixPostfixIncrementDecrement(
       String expr, UnlinkedExprAssignOperator expectedAssignmentOperator) {
-    if (skipNonConstInitializers) {
-      return;
-    }
     UnlinkedVariable variable = serializeVariableText('''
 int a = 0;
 final v = $expr;
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 6853053..d5cd7ac 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -4667,7 +4667,8 @@
     computeResult(target, VERIFY_ERRORS, matcher: isVerifyUnitTask);
     // validate
     _fillErrorListener(VERIFY_ERRORS);
-    errorListener.assertNoErrors();
+    errorListener.assertErrorsWithCodes(
+        <ErrorCode>[CompileTimeErrorCode.FOR_IN_WITH_CONST_VARIABLE]);
   }
 
   test_perform_ConstantValidator_dependencyCycle() {
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index 76c3312..bc4abcc 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -177,7 +177,7 @@
         new ResultDescriptor<String>('result', null);
     context
         .getCacheEntry(target)
-        .setValue(result, '', TargetedResult.EMPTY_LIST);
+        .setValue(result, '', const <TargetedResult>[]);
 
     expect(analysisDriver.createWorkOrderForResult(target, result), isNull);
   }
@@ -484,7 +484,7 @@
     if (complete) {
       context
           .getCacheEntry(target)
-          .setValue(result, '', TargetedResult.EMPTY_LIST);
+          .setValue(result, '', const <TargetedResult>[]);
     } else {
       context.getCacheEntry(target).setState(result, CacheState.INVALID);
     }
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 5f32672..c176d1d 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -20,6 +20,7 @@
         InstantiationConstantValue;
 import 'elements/types.dart';
 import 'elements/entities.dart';
+import 'kernel/kelements.dart' show KLocalFunction;
 import 'library_loader.dart';
 import 'universe/use.dart';
 import 'universe/world_impact.dart'
@@ -278,16 +279,7 @@
     // TODO(het): we would like to separate out types that are only needed for
     // rti from types that are needed for their members.
     if (type is FunctionType) {
-      for (DartType argumentType in type.parameterTypes) {
-        _collectTypeDependencies(argumentType, dependencies);
-      }
-      for (DartType argumentType in type.optionalParameterTypes) {
-        _collectTypeDependencies(argumentType, dependencies);
-      }
-      for (DartType argumentType in type.namedParameterTypes) {
-        _collectTypeDependencies(argumentType, dependencies);
-      }
-      _collectTypeDependencies(type.returnType, dependencies);
+      _collectFunctionTypeDependencies(type, dependencies);
     } else if (type is TypedefType) {
       type.typeArguments
           .forEach((t) => _collectTypeDependencies(t, dependencies));
@@ -299,6 +291,23 @@
     }
   }
 
+  void _collectFunctionTypeDependencies(
+      FunctionType type, Dependencies dependencies) {
+    for (FunctionTypeVariable typeVariable in type.typeVariables) {
+      _collectTypeDependencies(typeVariable.bound, dependencies);
+    }
+    for (DartType argumentType in type.parameterTypes) {
+      _collectTypeDependencies(argumentType, dependencies);
+    }
+    for (DartType argumentType in type.optionalParameterTypes) {
+      _collectTypeDependencies(argumentType, dependencies);
+    }
+    for (DartType argumentType in type.namedParameterTypes) {
+      _collectTypeDependencies(argumentType, dependencies);
+    }
+    _collectTypeDependencies(type.returnType, dependencies);
+  }
+
   /// Extract any dependencies that are known from the impact of [element].
   void _collectDependenciesFromImpact(
       MemberEntity element, Dependencies dependencies) {
@@ -307,14 +316,17 @@
         element,
         worldImpact,
         new WorldImpactVisitorImpl(visitStaticUse: (StaticUse staticUse) {
-          if (staticUse.element is MemberEntity) {
-            dependencies.members.add(staticUse.element);
+          Entity usedEntity = staticUse.element;
+          if (usedEntity is MemberEntity) {
+            dependencies.members.add(usedEntity);
           } else {
-            assert(
-                staticUse.element is Local,
-                failedAt(
-                    staticUse.element, "Unexpected static use $staticUse."));
-            dependencies.localFunctions.add(staticUse.element);
+            assert(usedEntity is KLocalFunction,
+                failedAt(usedEntity, "Unexpected static use $staticUse."));
+            KLocalFunction localFunction = usedEntity;
+            // TODO(sra): Consult KClosedWorld to see if signature is needed.
+            _collectFunctionTypeDependencies(
+                localFunction.functionType, dependencies);
+            dependencies.localFunctions.add(localFunction);
           }
           switch (staticUse.kind) {
             case StaticUseKind.CONSTRUCTOR_INVOKE:
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index e5759ba..9a5f781 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -1092,7 +1092,8 @@
       DartType type = _closedWorld.elementEnvironment.getFieldType(field);
       if (!type.treatAsRaw ||
           type.isTypeVariable ||
-          type.unaliased.isFunctionType) {
+          type.unaliased.isFunctionType ||
+          type.unaliased.isFutureOr) {
         // We cannot generate the correct type representation here, so don't
         // inline this access.
         // TODO(sra): If the input is such that we don't need a type check, we
diff --git a/pkg/front_end/lib/src/fasta/combinator.dart b/pkg/front_end/lib/src/fasta/combinator.dart
index 9f97607..5dfcf91 100644
--- a/pkg/front_end/lib/src/fasta/combinator.dart
+++ b/pkg/front_end/lib/src/fasta/combinator.dart
@@ -7,15 +7,30 @@
 class Combinator {
   final bool isShow;
 
+  final List<CombinatorIdentifier> identifiers;
+
   final Set<String> names;
 
-  Combinator(this.isShow, this.names, int charOffset, Uri fileUri);
+  Combinator(
+      this.isShow, this.identifiers, this.names, int charOffset, Uri fileUri);
 
-  Combinator.show(Iterable<String> names, int charOffset, Uri fileUri)
-      : this(true, new Set<String>.from(names), charOffset, fileUri);
+  Combinator.hide(List<CombinatorIdentifier> identifiers,
+      Iterable<String> names, int charOffset, Uri fileUri)
+      : this(false, identifiers, new Set<String>.from(names), charOffset,
+            fileUri);
 
-  Combinator.hide(Iterable<String> names, int charOffset, Uri fileUri)
-      : this(false, new Set<String>.from(names), charOffset, fileUri);
+  Combinator.show(List<CombinatorIdentifier> identifiers,
+      Iterable<String> names, int charOffset, Uri fileUri)
+      : this(true, identifiers, new Set<String>.from(names), charOffset,
+            fileUri);
 
   bool get isHide => !isShow;
 }
+
+class CombinatorIdentifier {
+  final int offset;
+  final String name;
+  final bool isSynthetic;
+
+  CombinatorIdentifier(this.offset, this.name, this.isSynthetic);
+}
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 537c775..a695393 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -974,6 +974,18 @@
     message: r"""Field isn't final, but constructor is 'const'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeConstConstructorRedirectionToNonConst =
+    messageConstConstructorRedirectionToNonConst;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageConstConstructorRedirectionToNonConst =
+    const MessageCode("ConstConstructorRedirectionToNonConst",
+        dart2jsCode: "*fatal*",
+        severity: Severity.error,
+        message:
+            r"""A constant constructor can't call a non-constant constructor.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeConstConstructorWithBody = messageConstConstructorWithBody;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3490,6 +3502,64 @@
     tip: r"""Try moving the with clause before the implements clause.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeImplementsFutureOr = messageImplementsFutureOr;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageImplementsFutureOr = const MessageCode(
+    "ImplementsFutureOr",
+    dart2jsCode: "*fatal*",
+    severity: Severity.error,
+    message: r"""'FutureOr' can't be used in an 'implements' clause.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name, int count)>
+    templateImplementsRepeated =
+    const Template<Message Function(String name, int count)>(
+        messageTemplate: r"""'#name' can only be implemented once.""",
+        tipTemplate: r"""Try removing #count of the occurrences.""",
+        withArguments: _withArgumentsImplementsRepeated);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, int count)> codeImplementsRepeated =
+    const Code<Message Function(String name, int count)>(
+        "ImplementsRepeated", templateImplementsRepeated,
+        analyzerCode: "IMPLEMENTS_REPEATED", dart2jsCode: "*fatal*");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsImplementsRepeated(String name, int count) {
+  return new Message(codeImplementsRepeated,
+      message: """'${name}' can only be implemented once.""",
+      tip: """Try removing ${count} of the occurrences.""",
+      arguments: {'name': name, 'count': count});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        String
+            name)> templateImplementsSuperClass = const Template<
+        Message Function(String name)>(
+    messageTemplate:
+        r"""'#name' can't be used in both 'extends' and 'implements' clauses.""",
+    tipTemplate: r"""Try removing one of the occurrences.""",
+    withArguments: _withArgumentsImplementsSuperClass);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeImplementsSuperClass =
+    const Code<Message Function(String name)>(
+        "ImplementsSuperClass", templateImplementsSuperClass,
+        analyzerCode: "IMPLEMENTS_SUPER_CLASS", dart2jsCode: "*fatal*");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsImplementsSuperClass(String name) {
+  return new Message(codeImplementsSuperClass,
+      message:
+          """'${name}' can't be used in both 'extends' and 'implements' clauses.""",
+      tip: """Try removing one of the occurrences.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
         DartType
@@ -6580,6 +6650,8 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageSuperAsIdentifier = const MessageCode(
     "SuperAsIdentifier",
+    analyzerCode: "SUPER_AS_EXPRESSION",
+    dart2jsCode: "*fatal*",
     message: r"""Expected identifier, but got 'super'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 476c2da..399112b 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -469,10 +469,10 @@
             combinators ??= <Combinator>[];
 
             combinators.add(combinator.isShow
-                ? new Combinator.show(
-                    combinator.names, combinator.fileOffset, library.fileUri)
-                : new Combinator.hide(
-                    combinator.names, combinator.fileOffset, library.fileUri));
+                ? new Combinator.show(null, combinator.names,
+                    combinator.fileOffset, library.fileUri)
+                : new Combinator.hide(null, combinator.names,
+                    combinator.fileOffset, library.fileUri));
           }
 
           debugLibrary.addImport(
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 81eb16d..4be50c6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1098,12 +1098,14 @@
         Expression argument = toValue(node);
         arguments[i] = argument;
         if (i > firstNamedArgumentIndex) {
-          arguments[i] = new NamedExpression(
-              "#$i",
+          arguments[i] = new NamedExpressionJudgment(
+              tokensSaver?.namedExpressionTokens(null, null),
+              '#$i',
               buildCompileTimeErrorExpression(
                   fasta.messageExpectedNamedArgument,
-                  forest.readOffset(argument)))
-            ..fileOffset = beginToken.charOffset;
+                  forest.readOffset(argument)),
+              originalValue: argument)
+            ..fileOffset = offsetForToken(beginToken);
         }
       }
     }
@@ -2776,27 +2778,29 @@
   @override
   void handleUnaryPrefixAssignmentExpression(Token token) {
     debugEvent("UnaryPrefixAssignmentExpression");
-    Object generator = pop();
-    if (generator is Generator) {
-      push(generator.buildPrefixIncrement(incrementOperator(token),
-          offset: token.charOffset));
+    Object target = pop();
+    Generator generator;
+    if (target is Generator) {
+      generator = target;
     } else {
-      push(
-          wrapInCompileTimeError(toValue(generator), fasta.messageNotAnLvalue));
+      generator = new KernelNonLValueGenerator(this, token, toValue(target));
     }
+    push(generator.buildPrefixIncrement(incrementOperator(token),
+        offset: token.charOffset));
   }
 
   @override
   void handleUnaryPostfixAssignmentExpression(Token token) {
     debugEvent("UnaryPostfixAssignmentExpression");
-    Object generator = pop();
-    if (generator is Generator) {
-      push(new DelayedPostfixIncrement(
-          this, token, generator, incrementOperator(token), null));
+    Object target = pop();
+    Generator generator;
+    if (target is Generator) {
+      generator = target;
     } else {
-      push(
-          wrapInCompileTimeError(toValue(generator), fasta.messageNotAnLvalue));
+      generator = new KernelNonLValueGenerator(this, token, toValue(target));
     }
+    push(new DelayedPostfixIncrement(
+        this, token, generator, incrementOperator(token), null));
   }
 
   @override
@@ -4341,7 +4345,7 @@
           constructor,
           forest.castArguments(arguments),
           buildCompileTimeError(fasta.messageConstConstructorWithNonConstSuper,
-              charOffset, member.name.length),
+              charOffset, constructor.name.name.length),
           charOffset);
     }
     needsImplicitSuperInitializer = false;
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index 05b2a4d..ec87044 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -68,6 +68,7 @@
         DartType,
         DynamicType,
         Expression,
+        IllegalAssignmentJudgment,
         Initializer,
         InvalidConstructorInvocationJudgment,
         InvalidType,
@@ -119,7 +120,8 @@
   ///
   /// The returned expression evaluates to the assigned value, unless
   /// [voidContext] is true, in which case it may evaluate to anything.
-  Expression buildAssignment(Expression value, {bool voidContext});
+  Expression buildAssignment(Expression value,
+      {bool voidContext, int offset: -1});
 
   /// Returns a [Expression] representing a null-aware assignment (`??=`) with
   /// the generator on the LHS and [value] on the RHS.
@@ -779,7 +781,8 @@
   }
 
   @override
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+  Expression buildAssignment(Expression value,
+      {bool voidContext: false, int offset: -1}) {
     return new SyntheticExpressionJudgment(buildError(
         forest.arguments(<Expression>[value], token, token),
         isSetter: true));
@@ -790,7 +793,8 @@
       {int offset: -1,
       bool voidContext: false,
       Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
+      bool isPreIncDec: false,
+      bool isPostIncDec: false}) {
     return new SyntheticExpressionJudgment(buildError(
         forest.arguments(<Expression>[value], token, token),
         isGetter: true));
@@ -937,15 +941,16 @@
   }
 
   @override
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
-    return makeInvalidWrite(value);
+  Expression buildAssignment(Expression value,
+      {bool voidContext: false, int offset: -1}) {
+    return buildInvalidAssignment(value, offset);
   }
 
   @override
   Expression buildNullAwareAssignment(
       Expression value, DartType type, int offset,
       {bool voidContext: false}) {
-    return makeInvalidWrite(value);
+    return buildInvalidAssignment(value, offset);
   }
 
   @override
@@ -953,20 +958,36 @@
       {int offset: -1,
       bool voidContext: false,
       Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
-    return makeInvalidWrite(value);
+      bool isPreIncDec: false,
+      bool isPostIncDec: false}) {
+    return buildInvalidAssignment(value, offset);
   }
 
   @override
   Expression buildPrefixIncrement(Name binaryOperator,
       {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
-    return makeInvalidWrite(null);
+    return buildInvalidAssignment(
+        forest.literalInt(1, null, isSynthetic: true), offset);
   }
 
   @override
   Expression buildPostfixIncrement(Name binaryOperator,
       {int offset: -1, bool voidContext: false, Procedure interfaceTarget}) {
-    return makeInvalidWrite(null);
+    return buildInvalidAssignment(
+        forest.literalInt(1, null, isSynthetic: true), offset);
+  }
+
+  Expression buildInvalidAssignment(Expression value, int offset) {
+    var lhs = buildSimpleRead();
+    // The lhs expression needs to have a parent so that type inference can be
+    // applied to it, but it doesn't matter what the parent is because the
+    // lhs expression won't appear in the tree.  So just give it a quick and
+    // dirty parent.
+    new VariableDeclaration.forValue(lhs);
+
+    return new IllegalAssignmentJudgment(value,
+        assignmentOffset: offset, desugared: makeInvalidWrite(value))
+      ..write = lhs;
   }
 
   @override
@@ -1025,7 +1046,8 @@
 
   Expression makeAssignmentExpression(bool voidContext) {
     if (identical("=", assignmentOperator)) {
-      return generator.buildAssignment(value, voidContext: voidContext);
+      return generator.buildAssignment(value,
+          voidContext: voidContext, offset: token.offset);
     } else if (identical("+=", assignmentOperator)) {
       return generator.buildCompoundAssignment(plusName, value,
           offset: offsetForToken(token), voidContext: voidContext);
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index ebd3eb6..42e8892 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -183,10 +183,11 @@
   }
 
   @override
-  IntJudgment literalInt(int value, Token token, {Expression desugaredError}) {
+  IntJudgment literalInt(int value, Token token,
+      {Expression desugaredError, bool isSynthetic: false}) {
     return new IntJudgment(
         typeInferenceTokensSaver?.intLiteralTokens(token), value,
-        desugaredError: desugaredError)
+        desugaredError: desugaredError, isSynthetic: isSynthetic)
       ..fileOffset = offsetForToken(token);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index db980e4..2e029e5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -76,7 +76,8 @@
 
   /// Return a representation of an integer literal at the given [location]. The
   /// literal has the given [value].
-  Expression literalInt(int value, Token location, {Expression desugaredError});
+  Expression literalInt(int value, Token location,
+      {Expression desugaredError, bool isSynthetic: false});
 
   /// Return a representation of a list literal. The [constKeyword] is the
   /// location of the `const` keyword, or `null` if there is no keyword. The
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
index 90bdaf3..d46c89c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_class_builder.dart
@@ -47,11 +47,14 @@
     show
         LocatedMessage,
         Message,
+        messageImplementsFutureOr,
         messagePatchClassOrigin,
         messagePatchClassTypeVariablesMismatch,
         messagePatchDeclarationMismatch,
         messagePatchDeclarationOrigin,
         noLength,
+        templateImplementsRepeated,
+        templateImplementsSuperClass,
         templateMissingImplementationCause,
         templateMissingImplementationNotAbstract,
         templateOverriddenMethodCause,
@@ -79,6 +82,7 @@
         KernelLibraryBuilder,
         KernelProcedureBuilder,
         KernelRedirectingFactoryBuilder,
+        KernelNamedTypeBuilder,
         KernelTypeBuilder,
         KernelTypeVariableBuilder,
         LibraryBuilder,
@@ -194,6 +198,64 @@
     }
   }
 
+  void checkSupertypes(CoreTypes coreTypes) {
+    // This method determines whether the class (that's being built) its super
+    // class appears both in 'extends' and 'implements' clauses and whether any
+    // interface appears multiple times in the 'implements' clause.
+    if (interfaces == null) return;
+
+    // Extract super class (if it exists).
+    ClassBuilder superClass;
+    KernelTypeBuilder superClassType = supertype;
+    if (superClassType is KernelNamedTypeBuilder) {
+      Declaration decl = superClassType.declaration;
+      if (decl is ClassBuilder) {
+        superClass = decl;
+      }
+    }
+
+    // Validate interfaces.
+    Map<ClassBuilder, int> problems;
+    Map<ClassBuilder, int> problemsOffsets;
+    Set<ClassBuilder> implemented = new Set<ClassBuilder>();
+    for (KernelTypeBuilder type in interfaces) {
+      if (type is KernelNamedTypeBuilder) {
+        Declaration decl = type.declaration;
+        if (decl is ClassBuilder) {
+          ClassBuilder interface = decl;
+          if (superClass == interface) {
+            addCompileTimeError(
+                templateImplementsSuperClass.withArguments(interface.name),
+                type.charOffset,
+                noLength);
+          } else if (implemented.contains(interface)) {
+            // Aggregate repetitions.
+            problems ??= new Map<ClassBuilder, int>();
+            problems[interface] ??= 0;
+            problems[interface] += 1;
+
+            problemsOffsets ??= new Map<ClassBuilder, int>();
+            problemsOffsets[interface] ??= type.charOffset;
+          } else if (interface.target == coreTypes.futureOrClass) {
+            addCompileTimeError(messageImplementsFutureOr, type.charOffset,
+                interface.target.name.length);
+          } else {
+            implemented.add(interface);
+          }
+        }
+      }
+    }
+    if (problems != null) {
+      problems.forEach((ClassBuilder interface, int repetitions) {
+        addCompileTimeError(
+            templateImplementsRepeated.withArguments(
+                interface.name, repetitions),
+            problemsOffsets[interface],
+            noLength);
+      });
+    }
+  }
+
   @override
   int resolveConstructors(LibraryBuilder library) {
     int count = super.resolveConstructors(library);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
index 90a8c07..004ea06 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator.dart
@@ -142,7 +142,8 @@
   }
 
   @override
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+  Expression buildAssignment(Expression value,
+      {bool voidContext: false, int offset: -1}) {
     var complexAssignment = startComplexAssignment(value);
     return _finish(_makeSimpleWrite(value, voidContext, complexAssignment),
         complexAssignment);
@@ -199,8 +200,8 @@
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget}) {
-    return buildCompoundAssignment(
-        binaryOperator, forest.literalInt(1, null)..fileOffset = offset,
+    return buildCompoundAssignment(binaryOperator,
+        forest.literalInt(1, null, isSynthetic: true)..fileOffset = offset,
         offset: offset,
         voidContext: voidContext,
         interfaceTarget: interfaceTarget,
@@ -213,8 +214,8 @@
       bool voidContext: false,
       Procedure interfaceTarget}) {
     if (voidContext) {
-      return buildCompoundAssignment(
-          binaryOperator, forest.literalInt(1, null)..fileOffset = offset,
+      return buildCompoundAssignment(binaryOperator,
+          forest.literalInt(1, null, isSynthetic: true)..fileOffset = offset,
           offset: offset,
           voidContext: voidContext,
           interfaceTarget: interfaceTarget,
@@ -501,7 +502,8 @@
 
   @override
   ComplexAssignmentJudgment startComplexAssignment(Expression rhs) =>
-      new PropertyAssignmentJudgment(null, rhs);
+      new PropertyAssignmentJudgment(null, rhs,
+          isSyntheticLhs: token.isSynthetic);
 
   @override
   void printOn(StringSink sink) {
@@ -1530,7 +1532,8 @@
       : super(helper, token);
 
   @override
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+  Expression buildAssignment(Expression value,
+      {bool voidContext: false, int offset: -1}) {
     return _buildUnresolvedVariableAssignment(false, value);
   }
 
@@ -1539,7 +1542,8 @@
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget,
-      bool isPreIncDec: false}) {
+      bool isPreIncDec: false,
+      bool isPostIncDec: false}) {
     return _buildUnresolvedVariableAssignment(true, value);
   }
 
@@ -1595,7 +1599,8 @@
         super(helper, token);
 
   @override
-  Expression buildAssignment(Expression value, {bool voidContext}) {
+  Expression buildAssignment(Expression value,
+      {bool voidContext, int offset: -1}) {
     return new PropertySet(receiver, name, value)
       ..fileOffset = offsetForToken(token);
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
index cbff91f..c9cfbf9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_expression_generator_impl.dart
@@ -135,7 +135,8 @@
     }
   }
 
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+  Expression buildAssignment(Expression value,
+      {bool voidContext: false, int offset: -1}) {
     return buildAssignmentError();
   }
 
@@ -260,7 +261,8 @@
     return unsupported("buildSimpleRead", offsetForToken(token), uri);
   }
 
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+  Expression buildAssignment(Expression value,
+      {bool voidContext: false, int offset: -1}) {
     return unsupported("buildAssignment", offsetForToken(token), uri);
   }
 
@@ -331,7 +333,8 @@
     return unsupported("buildSimpleRead", offsetForToken(token), uri);
   }
 
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+  Expression buildAssignment(Expression value,
+      {bool voidContext: false, int offset: -1}) {
     return unsupported("buildAssignment", offsetForToken(token), uri);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
index 11ed95df..5d79c08 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart
@@ -65,8 +65,6 @@
 
 import '../problems.dart' show unexpected, unhandled;
 
-import '../source/outline_listener.dart' show OutlineListener;
-
 import '../source/source_class_builder.dart' show SourceClassBuilder;
 
 import '../source/source_library_builder.dart'
@@ -150,13 +148,10 @@
   /// the error message is the corresponding value in the map.
   Map<String, String> unserializableExports;
 
-  final OutlineListener outlineListener;
-
   KernelLibraryBuilder(Uri uri, Uri fileUri, Loader loader, this.actualOrigin,
       [Scope scope, Library target])
       : library = target ??
             (actualOrigin?.library ?? new Library(uri, fileUri: fileUri)),
-        outlineListener = loader.createOutlineListener(fileUri),
         super(loader, fileUri, scope);
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index cd00ddb..bcd41f7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -559,7 +559,8 @@
   /// pre-decrement.
   bool isPreIncDec = false;
 
-  ComplexAssignmentJudgment(this.rhs) : super(null);
+  ComplexAssignmentJudgment(this.rhs, {Expression desugared})
+      : super(desugared);
 
   String toString() {
     var parts = _getToStringParts();
@@ -665,7 +666,7 @@
         combinedType = readType == null
             ? rhsType
             : inferrer.typeSchemaEnvironment
-                .getLeastUpperBound(readType, rhsType);
+                .getStandardUpperBound(readType, rhsType);
         if (inferrer.strongMode) {
           nullAwareCombiner.staticType = combinedType;
         }
@@ -756,7 +757,7 @@
     inferrer.inferExpression(otherwiseJudgment, typeContext, useLub,
         isVoidAllowed: true);
     inferredType = useLub
-        ? inferrer.typeSchemaEnvironment.getLeastUpperBound(
+        ? inferrer.typeSchemaEnvironment.getStandardUpperBound(
             thenJudgment.inferredType, otherwiseJudgment.inferredType)
         : greatestClosure(inferrer.coreTypes, typeContext);
     if (inferrer.strongMode) {
@@ -1438,13 +1439,9 @@
     // - Let T = greatest closure of K with respect to `?` if K is not `_`, else
     //   UP(t0, t1)
     // - Then the inferred type is T.
-    if (rhsType is VoidType) {
-      inferredType = rhsType;
-    } else {
-      inferredType = useLub
-          ? inferrer.typeSchemaEnvironment.getLeastUpperBound(lhsType, rhsType)
-          : greatestClosure(inferrer.coreTypes, typeContext);
-    }
+    inferredType = useLub
+        ? inferrer.typeSchemaEnvironment.getStandardUpperBound(lhsType, rhsType)
+        : greatestClosure(inferrer.coreTypes, typeContext);
     if (inferrer.strongMode) {
       body.staticType = inferredType;
     }
@@ -1492,8 +1489,9 @@
   /// If `-1`, then there is no separate location for invalid assignment.
   final int assignmentOffset;
 
-  IllegalAssignmentJudgment(ExpressionJudgment rhs, {this.assignmentOffset: -1})
-      : super(rhs) {
+  IllegalAssignmentJudgment(ExpressionJudgment rhs,
+      {this.assignmentOffset: -1, Expression desugared})
+      : super(rhs, desugared: desugared) {
     rhs.parent = this;
   }
 
@@ -1625,16 +1623,22 @@
 class IntJudgment extends IntLiteral implements ExpressionJudgment {
   IntLiteralTokens tokens;
   final kernel.Expression desugaredError;
+  final bool isSynthetic;
 
   DartType inferredType;
 
-  IntJudgment(this.tokens, int value, {this.desugaredError}) : super(value);
+  IntJudgment(this.tokens, int value,
+      {this.desugaredError, this.isSynthetic: false})
+      : super(value);
 
   @override
   Expression infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer, DartType typeContext) {
     inferredType = inferrer.coreTypes.intClass.rawType;
-    inferrer.listener.intLiteral(this, fileOffset, tokens, value, inferredType);
+    if (!isSynthetic) {
+      inferrer.listener
+          .intLiteral(this, fileOffset, tokens, value, inferredType);
+    }
     if (desugaredError != null) {
       parent.replaceChild(this, desugaredError);
       parent = null;
@@ -2234,10 +2238,11 @@
   /// If this assignment uses null-aware access (`?.`), the conditional
   /// expression that guards the access; otherwise `null`.
   ConditionalExpression nullAwareGuard;
+  final bool isSyntheticLhs;
 
   PropertyAssignmentJudgment(
       ExpressionJudgment receiver, ExpressionJudgment rhs,
-      {bool isSuper: false})
+      {bool isSuper: false, this.isSyntheticLhs: false})
       : super(receiver, rhs, isSuper);
 
   @override
@@ -2287,6 +2292,7 @@
     inferrer.listener.propertyAssign(
         this,
         write.fileOffset,
+        isSyntheticLhs,
         receiverType,
         inferrer.getRealTarget(writeMember),
         writeContext,
@@ -3710,10 +3716,17 @@
 
 /// Concrete shadow object representing a named expression.
 class NamedExpressionJudgment extends NamedExpression {
-  NamedExpressionTokens tokens;
+  final NamedExpressionTokens tokens;
 
-  NamedExpressionJudgment(this.tokens, String nameLexeme, Expression value)
-      : super(nameLexeme, value);
+  /// The original value that is wrapped by this synthetic named argument.
+  /// Its type will be inferred.
+  final Expression originalValue;
+
+  NamedExpressionJudgment(this.tokens, String nameLexeme, Expression value,
+      {this.originalValue})
+      : super(nameLexeme, value) {
+    originalValue?.parent = this;
+  }
 
   ExpressionJudgment get judgment => value;
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index f128a30..0715e41 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -59,6 +59,7 @@
         LocatedMessage,
         messageConstConstructorNonFinalField,
         messageConstConstructorNonFinalFieldCause,
+        messageConstConstructorRedirectionToNonConst,
         noLength,
         templateFinalFieldNotInitialized,
         templateFinalFieldNotInitializedByConstructor,
@@ -260,6 +261,7 @@
           computeCoreTypes();
           loader.computeHierarchy();
           loader.performTopLevelInference(myClasses);
+          loader.checkSupertypes(myClasses);
           loader.checkOverrides(myClasses);
           loader.checkAbstractMembers(myClasses);
           loader.addNoSuchMethodForwarders(myClasses);
@@ -656,6 +658,12 @@
       bool isRedirecting = false;
       for (Initializer initializer in constructor.initializers) {
         if (initializer is RedirectingInitializer) {
+          if (constructor.isConst && !initializer.target.isConst) {
+            builder.addCompileTimeError(
+                messageConstConstructorRedirectionToNonConst,
+                initializer.fileOffset,
+                initializer.target.name.name.length);
+          }
           isRedirecting = true;
           break;
         }
@@ -689,6 +697,7 @@
           constructor.function.body = new EmptyStatement();
           constructor.function.body.parent = constructor.function;
         }
+
         Set<Field> myInitializedFields = new Set<Field>();
         for (Initializer initializer in constructor.initializers) {
           if (initializer is FieldInitializer) {
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 49bf6ab..6ed6457 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -296,6 +296,11 @@
   }
 
   @override
+  void beginMixinDeclaration(Token mixinKeyword, Token name) {
+    listener?.beginMixinDeclaration(mixinKeyword, name);
+  }
+
+  @override
   void beginNamedFunctionExpression(Token token) {
     listener?.beginNamedFunctionExpression(token);
   }
@@ -732,6 +737,11 @@
   }
 
   @override
+  void endMixinDeclaration(Token token) {
+    listener?.endMixinDeclaration(token);
+  }
+
+  @override
   void endNamedFunctionExpression(Token endToken) {
     listener?.endNamedFunctionExpression(endToken);
   }
@@ -1118,6 +1128,16 @@
   }
 
   @override
+  void handleMixinHeader(Token mixinKeyword) {
+    listener?.handleMixinHeader(mixinKeyword);
+  }
+
+  @override
+  void handleMixinOn(Token onKeyword, int typeCount) {
+    listener?.handleMixinOn(onKeyword, typeCount);
+  }
+
+  @override
   void handleNamedArgument(Token colon) {
     listener?.handleNamedArgument(colon);
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index 460fec9..83d9acd 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -240,6 +240,9 @@
   /// expressions are required.
   final bool allowedInConstantExpression;
 
+  /// Indicated whether the `isSynthetic` flag is required for the identifier.
+  final bool requiresSyntheticFlag;
+
   final Template<_MessageWithArgument<Token>> recoveryTemplate;
 
   const IdentifierContext(this._name,
@@ -249,6 +252,7 @@
       this.isContinuation: false,
       this.isScopeReference: false,
       this.isBuiltInIdentifierAllowed: true,
+      this.requiresSyntheticFlag: false,
       bool allowedInConstantExpression,
       this.recoveryTemplate: templateExpectedIdentifier})
       : this.allowedInConstantExpression =
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index 9814c3b..078f2d6 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -81,7 +81,8 @@
 
 /// See [IdentifierContext.combinator].
 class CombinatorIdentifierContext extends IdentifierContext {
-  const CombinatorIdentifierContext() : super('combinator');
+  const CombinatorIdentifierContext()
+      : super('combinator', requiresSyntheticFlag: true);
 
   @override
   Token ensureIdentifier(Token token, Parser parser) {
@@ -154,10 +155,12 @@
 
 /// See [IdentifierContext.dottedName].
 class DottedNameIdentifierContext extends IdentifierContext {
-  const DottedNameIdentifierContext() : super('dottedName');
+  const DottedNameIdentifierContext()
+      : super('dottedName', requiresSyntheticFlag: true);
 
   const DottedNameIdentifierContext.continuation()
-      : super('dottedNameContinuation', isContinuation: true);
+      : super('dottedNameContinuation',
+            isContinuation: true, requiresSyntheticFlag: true);
 
   @override
   Token ensureIdentifier(Token token, Parser parser) {
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index d4fa7d9..803363f 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -136,6 +136,32 @@
     logEvent("ClassDeclaration");
   }
 
+  /// Handle the beginning of a mixin declaration.
+  void beginMixinDeclaration(Token mixinKeyword, Token name) {}
+
+  /// Handle an on clause in a mixin declaration. Substructures:
+  /// - implemented types
+  void handleMixinOn(Token onKeyword, int typeCount) {
+    logEvent("MixinOn");
+  }
+
+  /// Handle the header of a class declaration.  Substructures:
+  /// - metadata
+  /// - mixin name
+  /// - type variables
+  /// - on types
+  /// - implemented types
+  void handleMixinHeader(Token mixinKeyword) {
+    logEvent("MixinHeader");
+  }
+
+  /// Handle the end of a mixin declaration.  Substructures:
+  /// - mixin header
+  /// - class or mixin body
+  void endMixinDeclaration(Token token) {
+    logEvent("MixinDeclaration");
+  }
+
   void beginCombinators(Token token) {}
 
   void endCombinators(int count) {
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 40b3b4e..1885d3b 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -256,6 +256,9 @@
 
   bool mayParseFunctionExpressions = true;
 
+  // TODO(danrubel): remove this once mixin support is enabled by default.
+  bool isMixinSupportEnabled = false;
+
   /// Represents parser state: what asynchronous syntax is allowed in the
   /// function being currently parsed. In rare situations, this can be set by
   /// external clients, for example, to parse an expression outside a function.
@@ -574,8 +577,17 @@
         directiveState?.checkDeclaration();
         return parseTopLevelMemberImpl(start);
       } else {
+        // TODO(danrubel): Remove this once mixin support is enabled by default.
+        if (!isMixinSupportEnabled && identical(value, 'mixin')) {
+          directiveState?.checkDeclaration();
+          return parseTopLevelMemberImpl(start);
+        }
+
         parseTopLevelKeywordModifiers(start, keyword);
-        if (identical(value, 'typedef')) {
+        if (identical(value, 'mixin')) {
+          directiveState?.checkDeclaration();
+          return parseMixin(keyword);
+        } else if (identical(value, 'typedef')) {
           directiveState?.checkDeclaration();
           return parseTypedef(keyword);
         } else if (identical(value, 'library')) {
@@ -1845,6 +1857,63 @@
     return token;
   }
 
+  /// Parse a mixin declaration.
+  ///
+  /// ```
+  /// mixinDeclaration:
+  ///   metadata? 'mixin' [SimpleIdentifier] [TypeParameterList]?
+  ///        [OnClause]? [ImplementsClause]? '{' [ClassMember]* '}'
+  /// ;
+  /// ```
+  Token parseMixin(Token mixinKeyword) {
+    assert(optional('mixin', mixinKeyword));
+    Token name = ensureIdentifier(
+        mixinKeyword, IdentifierContext.classOrMixinDeclaration);
+    Token token = computeTypeParamOrArg(name, true).parseVariables(name, this);
+    listener.beginMixinDeclaration(mixinKeyword, name);
+    token = parseMixinHeaderOpt(token, mixinKeyword);
+    if (!optional('{', token.next)) {
+      // Recovery
+      token = parseMixinHeaderRecovery(mixinKeyword);
+      ensureBlock(token, fasta.templateExpectedClassOrMixinBody);
+    }
+    token = parseClassOrMixinBody(token);
+    listener.endMixinDeclaration(token);
+    return token;
+  }
+
+  Token parseMixinHeaderOpt(Token token, Token mixinKeyword) {
+    token = parseMixinOnOpt(token);
+    token = parseClassOrMixinImplementsOpt(token);
+    listener.handleMixinHeader(mixinKeyword);
+    return token;
+  }
+
+  Token parseMixinHeaderRecovery(Token mixinKeyword) {
+    // TODO(danrubel): Add mixin recovery similiar to class recovery.
+    return mixinKeyword;
+  }
+
+  /// ```
+  /// onClause:
+  ///   'on' typeName (',' typeName)*
+  /// ;
+  /// ```
+  Token parseMixinOnOpt(Token token) {
+    Token onKeyword;
+    int typeCount = 0;
+    if (optional('on', token.next)) {
+      onKeyword = token.next;
+      do {
+        token =
+            computeType(token.next, true).ensureTypeNotVoid(token.next, this);
+        ++typeCount;
+      } while (optional(',', token.next));
+    }
+    listener.handleMixinOn(onKeyword, typeCount);
+    return token;
+  }
+
   Token parseStringPart(Token token) {
     Token next = token.next;
     if (next.kind != STRING_TOKEN) {
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index fcab286..f4159f2 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -76,6 +76,11 @@
   int importExportDirectiveIndex = 0;
   int partDirectiveIndex = 0;
 
+  /// The unit currently being parsed, might be the same as [library] when
+  /// the defining unit of the library is being parsed, updated from outside
+  /// before parsing each part.
+  SourceLibraryBuilder currentUnit;
+
   ClassBuilder currentClass;
 
   /// For top-level declarations, this is the library scope. For class members,
@@ -121,7 +126,8 @@
       Token partKeyword, Token ofKeyword, Token semicolon, bool hasName) {
     debugEvent("PartOf");
     if (hasName) discard(1);
-    discard(1); // Metadata.
+    Token metadata = pop();
+    parseMetadata(currentUnit, metadata, currentUnit.target);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index d487929..6fc54ed 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -14,7 +14,7 @@
 
 import '../builder/metadata_builder.dart' show ExpressionMetadataBuilder;
 
-import '../combinator.dart' show Combinator;
+import '../combinator.dart' show Combinator, CombinatorIdentifier;
 
 import '../fasta_codes.dart'
     show
@@ -113,12 +113,14 @@
 
   int popCharOffset() => pop();
 
-  List<String> popIdentifierList(int count) {
+  List<CombinatorIdentifier> popIdentifierList(int count) {
     if (count == 0) return null;
-    List<String> list = new List<String>.filled(count, null, growable: true);
+    var list = new List<CombinatorIdentifier>.filled(count, null);
     for (int i = count - 1; i >= 0; i--) {
-      popCharOffset();
-      list[i] = pop();
+      bool isSynthetic = pop();
+      int offset = popCharOffset();
+      String name = pop();
+      list[i] = new CombinatorIdentifier(offset, name, isSynthetic);
     }
     return list;
   }
@@ -177,15 +179,21 @@
   @override
   void endHide(Token hideKeyword) {
     debugEvent("Hide");
-    List<String> names = pop();
-    push(new Combinator.hide(names, hideKeyword.charOffset, library.fileUri));
+    List<CombinatorIdentifier> identifiers = pop();
+    List<String> names =
+        identifiers.map((identifier) => identifier.name).toList();
+    push(new Combinator.hide(
+        identifiers, names, hideKeyword.charOffset, library.fileUri));
   }
 
   @override
   void endShow(Token showKeyword) {
     debugEvent("Show");
-    List<String> names = pop();
-    push(new Combinator.show(names, showKeyword.charOffset, library.fileUri));
+    List<CombinatorIdentifier> identifiers = pop();
+    List<String> names =
+        identifiers.map((identifier) => identifier.name).toList();
+    push(new Combinator.show(
+        identifiers, names, showKeyword.charOffset, library.fileUri));
   }
 
   @override
@@ -270,7 +278,9 @@
   @override
   void handleDottedName(int count, Token firstIdentifier) {
     debugEvent("DottedName");
-    push(popIdentifierList(count).join('.'));
+    push(popIdentifierList(count)
+        .map((identifier) => identifier.name)
+        .join('.'));
   }
 
   @override
@@ -319,6 +329,9 @@
       super.handleIdentifier(token, context);
       push(token.charOffset);
     }
+    if (context.requiresSyntheticFlag) {
+      push(token.isSynthetic);
+    }
     if (inConstructor && context == IdentifierContext.methodDeclaration) {
       inConstructorName = true;
     }
diff --git a/pkg/front_end/lib/src/fasta/source/outline_listener.dart b/pkg/front_end/lib/src/fasta/source/outline_listener.dart
index 4728332..0f77d6c 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_listener.dart
@@ -22,5 +22,8 @@
   /// `List<int>` will have a reference to `List` and type `List<int>`, i.e.
   /// with type arguments applied.
   void store(int offset, bool isSynthetic,
-      {int importIndex, Node reference, DartType type}) {}
+      {int importIndex,
+      bool isNamespaceCombinatorReference,
+      Node reference,
+      DartType type}) {}
 }
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 e6a127e..75ee308 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
@@ -65,6 +65,8 @@
 
 import '../problems.dart' show unhandled;
 
+import '../source/outline_listener.dart' show OutlineListener;
+
 import 'source_loader.dart' show SourceLoader;
 
 abstract class SourceLibraryBuilder<T extends TypeBuilder, R>
@@ -113,6 +115,8 @@
 
   bool canAddImplementationBuilders = false;
 
+  final OutlineListener outlineListener;
+
   SourceLibraryBuilder(SourceLoader loader, Uri fileUri, Scope scope)
       : this.fromScopes(loader, fileUri, new DeclarationBuilder<T>.library(),
             scope ?? new Scope.top());
@@ -121,6 +125,7 @@
       this.loader, this.fileUri, this.libraryDeclaration, this.importScope)
       : disableTypeInference = loader.target.disableTypeInference,
         currentDeclaration = libraryDeclaration,
+        outlineListener = loader.createOutlineListener(fileUri),
         super(
             fileUri, libraryDeclaration.toScope(importScope), new Scope.top());
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 638cd4d..cbe5078 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -45,6 +45,8 @@
         NamedTypeBuilder,
         TypeBuilder;
 
+import '../combinator.dart';
+
 import '../deprecated_problems.dart' show deprecated_inputError;
 
 import '../export.dart' show Export;
@@ -102,6 +104,8 @@
 
 import 'outline_builder.dart' show OutlineBuilder;
 
+import 'outline_listener.dart' show OutlineListener;
+
 import 'source_class_builder.dart' show SourceClassBuilder;
 
 import 'source_library_builder.dart' show SourceLibraryBuilder;
@@ -209,9 +213,13 @@
       // time we suppress lexical errors.
       Token tokens = await tokenize(library, suppressLexicalErrors: true);
       if (tokens == null) return;
+
       DietListener listener = createDietListener(library);
       DietParser parser = new DietParser(listener);
+
+      listener.currentUnit = library;
       parser.parseUnit(tokens);
+
       for (SourceLibraryBuilder part in library.parts) {
         if (part.partOfLibrary != library) {
           // Part was included in multiple libraries. Skip it here.
@@ -219,6 +227,7 @@
         }
         Token tokens = await tokenize(part);
         if (tokens != null) {
+          listener.currentUnit = part;
           listener.uri = part.fileUri;
           listener.partDirectiveIndex = 0;
           parser.parseUnit(tokens);
@@ -339,6 +348,21 @@
       // and can lead to memory leaks.
       exportee.exporters.clear();
     }
+    for (var library in builders.values) {
+      if (library is SourceLibraryBuilder) {
+        OutlineListener outlineListener = library.outlineListener;
+        if (outlineListener != null) {
+          for (var import in library.imports) {
+            storeCombinatorIdentifiersResolution(
+                outlineListener, import.imported, import.combinators);
+          }
+          for (var export in library.exports) {
+            storeCombinatorIdentifiersResolution(
+                outlineListener, export.exported, export.combinators);
+          }
+        }
+      }
+    }
     ticker.logMs("Computed library scopes");
     // debugPrintExports();
   }
@@ -702,6 +726,15 @@
     ticker.logMs("Computed core types");
   }
 
+  void checkSupertypes(List<SourceClassBuilder> sourceClasses) {
+    for (SourceClassBuilder builder in sourceClasses) {
+      if (builder.library.loader == this) {
+        builder.checkSupertypes(coreTypes);
+      }
+    }
+    ticker.logMs("Checked overrides");
+  }
+
   void checkOverrides(List<SourceClassBuilder> sourceClasses) {
     assert(hierarchy != null);
     for (SourceClassBuilder builder in sourceClasses) {
@@ -939,4 +972,19 @@
     hierarchy = null;
     typeInferenceEngine = null;
   }
+
+  void storeCombinatorIdentifiersResolution(OutlineListener outlineListener,
+      LibraryBuilder consumed, List<Combinator> combinators) {
+    if (combinators != null) {
+      for (var combinator in combinators) {
+        for (var identifier in combinator.identifiers) {
+          var declaration = consumed.exportScope.local[identifier.name];
+          declaration ??= consumed.exportScope.setters[identifier.name];
+          outlineListener.store(identifier.offset, identifier.isSynthetic,
+              isNamespaceCombinatorReference: true,
+              reference: declaration?.target);
+        }
+      }
+    }
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
index 3bd22e4..b3c28bb 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_listener.dart
@@ -643,6 +643,7 @@
   void propertyAssign(
       ExpressionJudgment judgment,
       Location location,
+      bool isSyntheticLhs,
       DartType receiverType,
       Reference writeMember,
       DartType writeContext,
@@ -1060,8 +1061,15 @@
       NullLiteralTokens tokens, bool isSynthetic, DartType inferredType) {}
 
   @override
-  void propertyAssign(ExpressionJudgment judgment, location, receiverType,
-      writeMember, DartType writeContext, combiner, DartType inferredType) {}
+  void propertyAssign(
+      ExpressionJudgment judgment,
+      location,
+      bool isSyntheticLhs,
+      receiverType,
+      writeMember,
+      DartType writeContext,
+      combiner,
+      DartType inferredType) {}
 
   @override
   void propertyGet(ExpressionJudgment judgment, location,
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index c53cd10..b8113fe 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -191,8 +191,6 @@
 
   final bool _needToInferReturnType;
 
-  final bool _needImplicitDowncasts;
-
   /// The type that actually appeared as the subexpression of `return` or
   /// `yield` statements inside the function.
   ///
@@ -204,12 +202,9 @@
   /// wrapping this type in `Stream` or `Iterator`, as appropriate.
   DartType _inferredUnwrappedReturnOrYieldType;
 
-  factory ClosureContext(
-      TypeInferrerImpl inferrer,
-      AsyncMarker asyncMarker,
-      DartType returnContext,
-      bool needToInferReturnType,
-      bool needImplicitDowncasts) {
+  factory ClosureContext(TypeInferrerImpl inferrer, AsyncMarker asyncMarker,
+      DartType returnContext, bool needToInferReturnType) {
+    assert(returnContext != null);
     DartType declaredReturnType = returnContext;
     bool isAsync = asyncMarker == AsyncMarker.Async ||
         asyncMarker == AsyncMarker.AsyncStar;
@@ -228,41 +223,77 @@
           inferrer.typeSchemaEnvironment.unfutureType(returnContext));
     }
     return new ClosureContext._(isAsync, isGenerator, returnContext,
-        declaredReturnType, needToInferReturnType, needImplicitDowncasts);
+        declaredReturnType, needToInferReturnType);
   }
 
-  ClosureContext._(
-      this.isAsync,
-      this.isGenerator,
-      this.returnOrYieldContext,
-      this.declaredReturnType,
-      this._needToInferReturnType,
-      this._needImplicitDowncasts) {
-    assert(returnOrYieldContext != null);
-  }
+  ClosureContext._(this.isAsync, this.isGenerator, this.returnOrYieldContext,
+      this.declaredReturnType, this._needToInferReturnType) {}
 
   /// Updates the inferred return type based on the presence of a return
   /// statement returning the given [type].
   void handleReturn(TypeInferrerImpl inferrer, DartType type,
       Expression expression, int fileOffset, bool isArrow) {
     if (isGenerator) return;
-    _updateInferredReturnType(
-        inferrer, type, expression, fileOffset, true, false, isArrow);
+    if (inferrer.ensureAssignable(
+            returnOrYieldContext, type, expression, fileOffset,
+            isReturnFromAsync: isAsync,
+            isReturn: true,
+            declaredReturnType: declaredReturnType,
+            isArrow: isArrow) !=
+        null) {
+      type = greatestClosure(inferrer.coreTypes, returnOrYieldContext);
+    }
+    if (_needToInferReturnType) {
+      var unwrappedType = type;
+      if (isAsync) {
+        unwrappedType = inferrer.typeSchemaEnvironment.unfutureType(type);
+      }
+      if (_inferredUnwrappedReturnOrYieldType == null) {
+        _inferredUnwrappedReturnOrYieldType = unwrappedType;
+      } else {
+        _inferredUnwrappedReturnOrYieldType = inferrer.typeSchemaEnvironment
+            .getStandardUpperBound(
+                _inferredUnwrappedReturnOrYieldType, unwrappedType);
+      }
+    }
   }
 
   void handleYield(TypeInferrerImpl inferrer, bool isYieldStar, DartType type,
       Expression expression, int fileOffset) {
     if (!isGenerator) return;
-    _updateInferredReturnType(
-        inferrer, type, expression, fileOffset, false, isYieldStar, false);
+    var expectedType = isYieldStar
+        ? _wrapAsyncOrGenerator(inferrer, returnOrYieldContext)
+        : returnOrYieldContext;
+    if (inferrer.ensureAssignable(expectedType, type, expression, fileOffset,
+            isReturnFromAsync: isAsync) !=
+        null) {
+      type = greatestClosure(inferrer.coreTypes, expectedType);
+    }
+    if (_needToInferReturnType) {
+      var unwrappedType = type;
+      if (isYieldStar) {
+        unwrappedType = inferrer.getDerivedTypeArgumentOf(
+                type,
+                isAsync
+                    ? inferrer.coreTypes.streamClass
+                    : inferrer.coreTypes.iterableClass) ??
+            type;
+      }
+      if (_inferredUnwrappedReturnOrYieldType == null) {
+        _inferredUnwrappedReturnOrYieldType = unwrappedType;
+      } else {
+        _inferredUnwrappedReturnOrYieldType = inferrer.typeSchemaEnvironment
+            .getStandardUpperBound(
+                _inferredUnwrappedReturnOrYieldType, unwrappedType);
+      }
+    }
   }
 
   DartType inferReturnType(TypeInferrerImpl inferrer) {
     assert(_needToInferReturnType);
     DartType inferredType =
         inferrer.inferReturnType(_inferredUnwrappedReturnOrYieldType);
-    if (returnOrYieldContext != null &&
-        !_analyzerSubtypeOf(inferrer, inferredType, returnOrYieldContext)) {
+    if (!_analyzerSubtypeOf(inferrer, inferredType, returnOrYieldContext)) {
       // If the inferred return type isn't a subtype of the context, we use the
       // context.
       inferredType = greatestClosure(inferrer.coreTypes, returnOrYieldContext);
@@ -271,53 +302,6 @@
     return _wrapAsyncOrGenerator(inferrer, inferredType);
   }
 
-  void _updateInferredReturnType(
-      TypeInferrerImpl inferrer,
-      DartType type,
-      Expression expression,
-      int fileOffset,
-      bool isReturn,
-      bool isYieldStar,
-      bool isArrow) {
-    if (_needImplicitDowncasts) {
-      var expectedType = isYieldStar
-          ? _wrapAsyncOrGenerator(inferrer, returnOrYieldContext)
-          : returnOrYieldContext;
-      if (expectedType != null) {
-        expectedType = greatestClosure(inferrer.coreTypes, expectedType);
-        if (inferrer.ensureAssignable(
-                expectedType, type, expression, fileOffset,
-                isReturnFromAsync: isAsync,
-                isReturn: isReturn,
-                declaredReturnType: declaredReturnType,
-                isArrow: isArrow) !=
-            null) {
-          type = expectedType;
-        }
-      }
-    }
-    var unwrappedType = type;
-    if (isAsync && isReturn) {
-      unwrappedType = inferrer.typeSchemaEnvironment.unfutureType(type);
-    } else if (isYieldStar) {
-      unwrappedType = inferrer.getDerivedTypeArgumentOf(
-              type,
-              isAsync
-                  ? inferrer.coreTypes.streamClass
-                  : inferrer.coreTypes.iterableClass) ??
-          type;
-    }
-    if (_needToInferReturnType) {
-      if (_inferredUnwrappedReturnOrYieldType == null) {
-        _inferredUnwrappedReturnOrYieldType = unwrappedType;
-      } else {
-        _inferredUnwrappedReturnOrYieldType = inferrer.typeSchemaEnvironment
-            .getLeastUpperBound(
-                _inferredUnwrappedReturnOrYieldType, unwrappedType);
-      }
-    }
-  }
-
   DartType _wrapAsyncOrGenerator(TypeInferrerImpl inferrer, DartType type) {
     if (isGenerator) {
       if (isAsync) {
@@ -1255,8 +1239,7 @@
       Statement body) {
     assert(closureContext == null);
     this.helper = helper;
-    closureContext =
-        new ClosureContext(this, asyncMarker, returnType, false, true);
+    closureContext = new ClosureContext(this, asyncMarker, returnType, false);
     inferStatement(body);
     closureContext = null;
     this.helper = null;
@@ -1561,13 +1544,8 @@
     // to `xi` in `B` having type `Pi`.  This produces `B’`.
     bool needToSetReturnType = hasImplicitReturnType && strongMode;
     ClosureContext oldClosureContext = this.closureContext;
-    bool needImplicitDowncasts = returnContext != null;
     ClosureContext closureContext = new ClosureContext(
-        this,
-        function.asyncMarker,
-        returnContext,
-        needToSetReturnType,
-        needImplicitDowncasts);
+        this, function.asyncMarker, returnContext, needToSetReturnType);
     this.closureContext = closureContext;
     inferStatement(function.body);
 
@@ -1978,13 +1956,14 @@
     return new InterfaceType(class_, <DartType>[type ?? const DynamicType()]);
   }
 
-  void _forEachArgument(
-      Arguments arguments, void callback(String name, Expression expression)) {
+  void _forEachArgument(ArgumentsJudgment arguments,
+      void callback(String name, Expression expression)) {
     for (var expression in arguments.positional) {
       callback(null, expression);
     }
-    for (var namedExpression in arguments.named) {
-      callback(namedExpression.name, namedExpression.value);
+    for (var namedExpression in arguments.namedJudgments) {
+      callback(namedExpression.name,
+          namedExpression.originalValue ?? namedExpression.value);
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index 5577ced..8b5aac7 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -94,25 +94,29 @@
 
   /// Modify the given [constraint]'s lower bound to include [lower].
   void addLowerBound(TypeConstraint constraint, DartType lower) {
-    constraint.lower = getLeastUpperBound(constraint.lower, lower);
+    constraint.lower = getStandardUpperBound(constraint.lower, lower);
   }
 
   /// Modify the given [constraint]'s upper bound to include [upper].
   void addUpperBound(TypeConstraint constraint, DartType upper) {
-    constraint.upper = getGreatestLowerBound(constraint.upper, upper);
+    constraint.upper = getStandardLowerBound(constraint.upper, upper);
   }
 
-  /// Computes the greatest lower bound of [type1] and [type2].
-  DartType getGreatestLowerBound(DartType type1, DartType type2) {
-    // The greatest lower bound relation is reflexive.  Note that we don't test
-    // for equality because we don't want to make the algorithm quadratic.  This
-    // is ok because the check is not needed for correctness; it's just a speed
+  /// Computes the standard lower bound of [type1] and [type2].
+  ///
+  /// Standard lower bound is a lower bound function that imposes an
+  /// ordering on the top types `void`, `dynamic`, and `object`.  This function
+  /// additionally handles the unknown type that appears during type inference.
+  DartType getStandardLowerBound(DartType type1, DartType type2) {
+    // For all types T, SLB(T,T) = T.  Note that we don't test for equality
+    // because we don't want to make the algorithm quadratic.  This is ok
+    // because the check is not needed for correctness; it's just a speed
     // optimization.
     if (identical(type1, type2)) {
       return type1;
     }
 
-    // For any type T, GLB(?, T) == T.
+    // For any type T, SLB(?, T) = SLB(T, ?) = T.
     if (type1 is UnknownType) {
       return type2;
     }
@@ -120,22 +124,45 @@
       return type1;
     }
 
-    // The GLB of top and any type is just that type.
-    // Also GLB of bottom and any type is bottom.
-    if (isTop(type1) || isBottom(type2)) {
+    // SLB(void, T) = SLB(T, void) = T.
+    if (type1 is VoidType) {
       return type2;
     }
-    if (isTop(type2) || isBottom(type1)) {
+    if (type2 is VoidType) {
       return type1;
     }
 
-    // Function types have structural GLB.
-    if (type1 is FunctionType && type2 is FunctionType) {
-      return _functionGreatestLowerBound(type1, type2);
+    // SLB(dynamic, T) = SLB(T, dynamic) = T if T is not void.
+    if (type1 is DynamicType) {
+      return type2;
+    }
+    if (type2 is DynamicType) {
+      return type1;
     }
 
-    // Otherwise, the GLB of two types is one of them it if it is a subtype of
-    // the other.
+    // SLB(Object, T) = SLB(T, Object) = T if T is not void or dynamic.
+    if (type1 == objectType) {
+      return type2;
+    }
+    if (type2 == objectType) {
+      return type1;
+    }
+
+    // SLB(bottom, T) = SLB(T, bottom) = bottom.
+    if (isBottom(type1)) {
+      return type1;
+    }
+    if (isBottom(type2)) {
+      return type2;
+    }
+
+    // Function types have structural lower bounds.
+    if (type1 is FunctionType && type2 is FunctionType) {
+      return _functionStandardLowerBound(type1, type2);
+    }
+
+    // Otherwise, the lower bounds  of two types is one of them it if it is a
+    // subtype of the other.
     if (isSubtypeOf(type1, type2)) {
       return type1;
     }
@@ -144,21 +171,25 @@
       return type2;
     }
 
-    // No subtype relation, so no known GLB.
+    // No subtype relation, so the lower bound is bottom.
     return const BottomType();
   }
 
-  /// Compute the least upper bound of two types.
-  DartType getLeastUpperBound(DartType type1, DartType type2) {
-    // The least upper bound relation is reflexive.  Note that we don't test
-    // for equality because we don't want to make the algorithm quadratic.  This
-    // is ok because the check is not needed for correctness; it's just a speed
+  /// Computes the standard upper bound of two types.
+  ///
+  /// Standard upper bound is an upper bound function that imposes an ordering
+  /// on the top types 'void', 'dynamic', and `object`.  This function
+  /// additionally handles the unknown type that appears during type inference.
+  DartType getStandardUpperBound(DartType type1, DartType type2) {
+    // For all types T, SUB(T,T) = T.  Note that we don't test for equality
+    // because we don't want to make the algorithm quadratic.  This is ok
+    // because the check is not needed for correctness; it's just a speed
     // optimization.
     if (identical(type1, type2)) {
       return type1;
     }
 
-    // For any type T, LUB(?, T) == T.
+    // For any type T, SUB(?, T) = SUB(T, ?) = T.
     if (type1 is UnknownType) {
       return type2;
     }
@@ -166,29 +197,44 @@
       return type1;
     }
 
-    // The least upper bound of void and any type T != dynamic is void.
+    // SUB(void, T) = SUB(T, void) = void.
     if (type1 is VoidType) {
-      return type2 is DynamicType ? type2 : type1;
-    }
-    if (type2 is VoidType) {
-      return type1 is DynamicType ? type1 : type2;
-    }
-
-    // The least upper bound of top and any type T is top.
-    // The least upper bound of bottom and any type T is T.
-    if (isTop(type1) || isBottom(type2)) {
       return type1;
     }
-    if (isTop(type2) || isBottom(type1)) {
+    if (type2 is VoidType) {
       return type2;
     }
 
-    if (type1 is TypeParameterType || type2 is TypeParameterType) {
-      return _typeParameterLeastUpperBound(type1, type2);
+    // SUB(dynamic, T) = SUB(T, dynamic) = dynamic if T is not void.
+    if (type1 is DynamicType) {
+      return type1;
+    }
+    if (type2 is DynamicType) {
+      return type2;
     }
 
-    // The least upper bound of a function type and an interface type T is the
-    // least upper bound of Function and T.
+    // SUB(Obect, T) = SUB(T, Object) = Object if T is not void or dynamic.
+    if (type1 == objectType) {
+      return type1;
+    }
+    if (type2 == objectType) {
+      return type2;
+    }
+
+    // SUB(bottom, T) = SUB(T, bottom) = T.
+    if (isBottom(type1)) {
+      return type2;
+    }
+    if (isBottom(type2)) {
+      return type1;
+    }
+
+    if (type1 is TypeParameterType || type2 is TypeParameterType) {
+      return _typeParameterStandardUpperBound(type1, type2);
+    }
+
+    // The standard upper bound of a function type and an interface type T is
+    // the standard upper bound of Function and T.
     if (type1 is FunctionType && type2 is InterfaceType) {
       type1 = rawFunctionType;
     }
@@ -199,11 +245,11 @@
     // At this point type1 and type2 should both either be interface types or
     // function types.
     if (type1 is InterfaceType && type2 is InterfaceType) {
-      return _interfaceLeastUpperBound(type1, type2);
+      return _interfaceStandardUpperBound(type1, type2);
     }
 
     if (type1 is FunctionType && type2 is FunctionType) {
-      return _functionLeastUpperBound(type1, type2);
+      return _functionStandardUpperBound(type1, type2);
     }
 
     // Should never happen. As a defensive measure, return the dynamic type.
@@ -327,9 +373,9 @@
       var typeParamBound = typeParam.bound;
       DartType extendsConstraint;
       if (!hasOmittedBound(typeParam)) {
-        extendsConstraint = Substitution
-            .fromPairs(typeParametersToInfer, inferredTypes)
-            .substituteType(typeParamBound);
+        extendsConstraint =
+            Substitution.fromPairs(typeParametersToInfer, inferredTypes)
+                .substituteType(typeParamBound);
       }
 
       var constraint = constraints[typeParam];
@@ -353,9 +399,9 @@
     for (int i = 0; i < typeParametersToInfer.length; i++) {
       TypeParameter typeParam = typeParametersToInfer[i];
       var constraint = constraints[typeParam];
-      var typeParamBound = Substitution
-          .fromPairs(typeParametersToInfer, inferredTypes)
-          .substituteType(typeParam.bound);
+      var typeParamBound =
+          Substitution.fromPairs(typeParametersToInfer, inferredTypes)
+              .substituteType(typeParam.bound);
 
       var inferred = inferredTypes[i];
       bool success = typeSatisfiesConstraint(inferred, constraint);
@@ -460,9 +506,9 @@
         isSubtypeOf(type, constraint.upper);
   }
 
-  /// Compute the greatest lower bound of function types [f] and [g].
+  /// Compute the standard lower bound of function types [f] and [g].
   ///
-  /// The spec rules for GLB on function types, informally, are pretty simple:
+  /// The spec rules for SLB on function types, informally, are pretty simple:
   ///
   /// - If a parameter is required in both, it stays required.
   ///
@@ -473,15 +519,15 @@
   ///
   /// - Named parameters are unioned together.
   ///
-  /// - For any parameter that exists in both functions, use the LUB of them as
+  /// - For any parameter that exists in both functions, use the SUB of them as
   ///   the resulting parameter type.
   ///
-  /// - Use the GLB of their return types.
-  DartType _functionGreatestLowerBound(FunctionType f, FunctionType g) {
+  /// - Use the SLB of their return types.
+  DartType _functionStandardLowerBound(FunctionType f, FunctionType g) {
     // TODO(rnystrom,paulberry): Right now, this assumes f and g do not have any
     // type parameters. Revisit that in the presence of generic methods.
 
-    // Calculate the LUB of each corresponding pair of parameters.
+    // Calculate the SUB of each corresponding pair of parameters.
     int totalPositional =
         math.max(f.positionalParameters.length, g.positionalParameters.length);
     var positionalParameters = new List<DartType>(totalPositional);
@@ -490,7 +536,7 @@
         var fType = f.positionalParameters[i];
         if (i < g.positionalParameters.length) {
           var gType = g.positionalParameters[i];
-          positionalParameters[i] = getLeastUpperBound(fType, gType);
+          positionalParameters[i] = getStandardUpperBound(fType, gType);
         } else {
           positionalParameters[i] = fType;
         }
@@ -524,7 +570,7 @@
             } else {
               namedParameters.add(new NamedType(
                   fName,
-                  getLeastUpperBound(f.namedParameters[i++].type,
+                  getStandardUpperBound(f.namedParameters[i++].type,
                       g.namedParameters[j++].type)));
             }
           } else {
@@ -543,16 +589,16 @@
     // and named parameters. If we would synthesize that, give up.
     if (hasPositional && hasNamed) return const BottomType();
 
-    // Calculate the GLB of the return type.
-    DartType returnType = getGreatestLowerBound(f.returnType, g.returnType);
+    // Calculate the SLB of the return type.
+    DartType returnType = getStandardLowerBound(f.returnType, g.returnType);
     return new FunctionType(positionalParameters, returnType,
         namedParameters: namedParameters,
         requiredParameterCount: requiredParameterCount);
   }
 
-  /// Compute the least upper bound of function types [f] and [g].
+  /// Compute the standard upper bound of function types [f] and [g].
   ///
-  /// The rules for LUB on function types, informally, are pretty simple:
+  /// The rules for SUB on function types, informally, are pretty simple:
   ///
   /// - If the functions don't have the same number of required parameters,
   ///   always return `Function`.
@@ -560,29 +606,29 @@
   /// - Discard any optional named or positional parameters the two types do not
   ///   have in common.
   ///
-  /// - Compute the GLB of each corresponding pair of parameter types, and the
-  ///   LUB of the return types.  Return a function type with those types.
-  DartType _functionLeastUpperBound(FunctionType f, FunctionType g) {
+  /// - Compute the SLB of each corresponding pair of parameter types, and the
+  ///   SUB of the return types.  Return a function type with those types.
+  DartType _functionStandardUpperBound(FunctionType f, FunctionType g) {
     // TODO(rnystrom): Right now, this assumes f and g do not have any type
     // parameters. Revisit that in the presence of generic methods.
 
     // If F and G differ in their number of required parameters, then the
-    // least upper bound of F and G is Function.
+    // standard upper bound of F and G is Function.
     // TODO(paulberry): We could do better here, e.g.:
-    //   LUB(([int]) -> void, (int) -> void) = (int) -> void
+    //   SUB(([int]) -> void, (int) -> void) = (int) -> void
     if (f.requiredParameterCount != g.requiredParameterCount) {
       return coreTypes.functionClass.rawType;
     }
     int requiredParameterCount = f.requiredParameterCount;
 
-    // Calculate the GLB of each corresponding pair of parameters.
+    // Calculate the SLB of each corresponding pair of parameters.
     // Ignore any extra optional positional parameters if one has more than the
     // other.
     int totalPositional =
         math.min(f.positionalParameters.length, g.positionalParameters.length);
     var positionalParameters = new List<DartType>(totalPositional);
     for (int i = 0; i < totalPositional; i++) {
-      positionalParameters[i] = getGreatestLowerBound(
+      positionalParameters[i] = getStandardLowerBound(
           f.positionalParameters[i], g.positionalParameters[i]);
     }
 
@@ -604,7 +650,7 @@
             } else {
               namedParameters.add(new NamedType(
                   fName,
-                  getGreatestLowerBound(f.namedParameters[i++].type,
+                  getStandardLowerBound(f.namedParameters[i++].type,
                       g.namedParameters[j++].type)));
             }
           } else {
@@ -616,8 +662,8 @@
       }
     }
 
-    // Calculate the LUB of the return type.
-    DartType returnType = getLeastUpperBound(f.returnType, g.returnType);
+    // Calculate the SUB of the return type.
+    DartType returnType = getStandardUpperBound(f.returnType, g.returnType);
     return new FunctionType(positionalParameters, returnType,
         namedParameters: namedParameters,
         requiredParameterCount: requiredParameterCount);
@@ -661,20 +707,21 @@
     return t;
   }
 
-  DartType _interfaceLeastUpperBound(InterfaceType type1, InterfaceType type2) {
-    // This currently does not implement a very complete least upper bound
+  DartType _interfaceStandardUpperBound(
+      InterfaceType type1, InterfaceType type2) {
+    // This currently does not implement a very complete standard upper bound
     // algorithm, but handles a couple of the very common cases that are
     // causing pain in real code.  The current algorithm is:
     // 1. If either of the types is a supertype of the other, return it.
     //    This is in fact the best result in this case.
     // 2. If the two types have the same class element, then take the
-    //    pointwise least upper bound of the type arguments.  This is again
+    //    pointwise standard upper bound of the type arguments.  This is again
     //    the best result, except that the recursive calls may not return
-    //    the true least upper bounds.  The result is guaranteed to be a
+    //    the true standard upper bounds.  The result is guaranteed to be a
     //    well-formed type under the assumption that the input types were
     //    well-formed (and assuming that the recursive calls return
     //    well-formed types).
-    // 3. Otherwise return the spec-defined least upper bound.  This will
+    // 3. Otherwise return the spec-defined standard upper bound.  This will
     //    be an upper bound, might (or might not) be least, and might
     //    (or might not) be a well-formed type.
     if (isSubtypeOf(type1, type2)) {
@@ -692,24 +739,24 @@
       assert(tArgs1.length == tArgs2.length);
       List<DartType> tArgs = new List(tArgs1.length);
       for (int i = 0; i < tArgs1.length; i++) {
-        tArgs[i] = getLeastUpperBound(tArgs1[i], tArgs2[i]);
+        tArgs[i] = getStandardUpperBound(tArgs1[i], tArgs2[i]);
       }
       return new InterfaceType(type1.classNode, tArgs);
     }
     return hierarchy.getClassicLeastUpperBound(type1, type2);
   }
 
-  DartType _typeParameterLeastUpperBound(DartType type1, DartType type2) {
-    // This currently just implements a simple least upper bound to
+  DartType _typeParameterStandardUpperBound(DartType type1, DartType type2) {
+    // This currently just implements a simple standard upper bound to
     // handle some common cases.  It also avoids some termination issues
-    // with the naive spec algorithm.  The least upper bound of two types
+    // with the naive spec algorithm.  The standard upper bound of two types
     // (at least one of which is a type parameter) is computed here as:
     // 1. If either type is a supertype of the other, return it.
     // 2. If the first type is a type parameter, replace it with its bound,
     //    with recursive occurrences of itself replaced with Object.
     //    The second part of this should ensure termination.  Informally,
     //    each type variable instantiation in one of the arguments to the
-    //    least upper bound algorithm now strictly reduces the number
+    //    standard upper bound algorithm now strictly reduces the number
     //    of bound variables in scope in that argument position.
     // 3. If the second type is a type parameter, do the symmetric operation
     //    to #2.
@@ -742,15 +789,15 @@
       // TODO(paulberry): Analyzer collapses simple bounds in one step, i.e. for
       // C<T extends U, U extends List>, T gets resolved directly to List.  Do
       // we need to replicate that behavior?
-      return getLeastUpperBound(
-          Substitution.fromMap({type1.parameter: objectType}).substituteType(
-              type1.parameter.bound),
+      return getStandardUpperBound(
+          Substitution.fromMap({type1.parameter: objectType})
+              .substituteType(type1.parameter.bound),
           type2);
     } else if (type2 is TypeParameterType) {
-      return getLeastUpperBound(
+      return getStandardUpperBound(
           type1,
-          Substitution.fromMap({type2.parameter: objectType}).substituteType(
-              type2.parameter.bound));
+          Substitution.fromMap({type2.parameter: objectType})
+              .substituteType(type2.parameter.bound));
     } else {
       // We should only be called when at least one of the types is a
       // TypeParameterType
diff --git a/pkg/front_end/lib/src/scanner/scanner.dart b/pkg/front_end/lib/src/scanner/scanner.dart
deleted file mode 100644
index 26e2f29..0000000
--- a/pkg/front_end/lib/src/scanner/scanner.dart
+++ /dev/null
@@ -1,1337 +0,0 @@
-// 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:charcode/ascii.dart';
-
-import 'errors.dart';
-import 'reader.dart';
-import 'string_utilities.dart';
-import 'token.dart';
-
-/**
- * A state in a state machine used to scan keywords.
- */
-class KeywordState {
-  /**
-   * An empty transition table used by leaf states.
-   */
-  static List<KeywordState> _EMPTY_TABLE = new List<KeywordState>($z - $A + 1);
-
-  /**
-   * The initial state in the state machine.
-   */
-  static final KeywordState KEYWORD_STATE = _createKeywordStateTable();
-
-  /**
-   * A table mapping characters to the states to which those characters will
-   * transition. (The index into the array is the offset from the character
-   * `'a'` to the transitioning character.)
-   */
-  final List<KeywordState> _table;
-
-  /**
-   * The keyword that is recognized by this state, or `null` if this state is
-   * not a terminal state.
-   */
-  Keyword _keyword;
-
-  /**
-   * Initialize a newly created state to have the given transitions and to
-   * recognize the keyword with the given [syntax].
-   */
-  KeywordState(this._table, String syntax) {
-    this._keyword = (syntax == null) ? null : Keyword.keywords[syntax];
-  }
-
-  /**
-   * Return the keyword that was recognized by this state, or `null` if this
-   * state does not recognized a keyword.
-   */
-  Keyword keyword() => _keyword;
-
-  /**
-   * Return the state that follows this state on a transition of the given
-   * [character], or `null` if there is no valid state reachable from this state
-   * with such a transition.
-   */
-  KeywordState next(int character) => _table[character - $A];
-
-  /**
-   * Create the next state in the state machine where we have already recognized
-   * the subset of strings in the given array of [strings] starting at the given
-   * [offset] and having the given [length]. All of these strings have a common
-   * prefix and the next character is at the given [start] index.
-   */
-  static KeywordState _computeKeywordStateTable(
-      int start, List<String> strings, int offset, int length) {
-    List<KeywordState> result = new List<KeywordState>($z - $A + 1);
-    assert(length != 0);
-    int chunk = $nul;
-    int chunkStart = -1;
-    bool isLeaf = false;
-    for (int i = offset; i < offset + length; i++) {
-      if (strings[i].length == start) {
-        isLeaf = true;
-      }
-      if (strings[i].length > start) {
-        int c = strings[i].codeUnitAt(start);
-        if (chunk != c) {
-          if (chunkStart != -1) {
-            result[chunk - $A] = _computeKeywordStateTable(
-                start + 1, strings, chunkStart, i - chunkStart);
-          }
-          chunkStart = i;
-          chunk = c;
-        }
-      }
-    }
-    if (chunkStart != -1) {
-      assert(result[chunk - $A] == null);
-      result[chunk - $A] = _computeKeywordStateTable(
-          start + 1, strings, chunkStart, offset + length - chunkStart);
-    } else {
-      assert(length == 1);
-      return new KeywordState(_EMPTY_TABLE, strings[offset]);
-    }
-    if (isLeaf) {
-      return new KeywordState(result, strings[offset]);
-    } else {
-      return new KeywordState(result, null);
-    }
-  }
-
-  /**
-   * Create and return the initial state in the state machine.
-   */
-  static KeywordState _createKeywordStateTable() {
-    List<Keyword> values = Keyword.values;
-    List<String> strings = new List<String>(values.length);
-    for (int i = 0; i < values.length; i++) {
-      strings[i] = values[i].lexeme;
-    }
-    strings.sort();
-    return _computeKeywordStateTable(0, strings, 0, strings.length);
-  }
-}
-
-/**
- * The class `Scanner` implements a scanner for Dart code.
- *
- * The lexical structure of Dart is ambiguous without knowledge of the context
- * in which a token is being scanned. For example, without context we cannot
- * determine whether source of the form "<<" should be scanned as a single
- * left-shift operator or as two left angle brackets. This scanner does not have
- * any context, so it always resolves such conflicts by scanning the longest
- * possible token.
- */
-abstract class Scanner {
-  /**
-   * The reader used to access the characters in the source.
-   */
-  final CharacterReader _reader;
-
-  /**
-   * The flag specifying whether documentation comments should be parsed.
-   */
-  bool _preserveComments = true;
-
-  /**
-   * The token pointing to the head of the linked list of tokens.
-   */
-  Token _tokens;
-
-  /**
-   * The last token that was scanned.
-   */
-  Token _tail;
-
-  /**
-   * The first token in the list of comment tokens found since the last
-   * non-comment token.
-   */
-  Token _firstComment;
-
-  /**
-   * The last token in the list of comment tokens found since the last
-   * non-comment token.
-   */
-  Token _lastComment;
-
-  /**
-   * The index of the first character of the current token.
-   */
-  int _tokenStart = 0;
-
-  /**
-   * A list containing the offsets of the first character of each line in the
-   * source code.
-   */
-  List<int> _lineStarts = new List<int>();
-
-  /**
-   * A list, treated something like a stack, of tokens representing the
-   * beginning of a matched pair. It is used to pair the end tokens with the
-   * begin tokens.
-   */
-  List<BeginToken> _groupingStack = new List<BeginToken>();
-
-  /**
-   * The index of the last item in the [_groupingStack], or `-1` if the stack is
-   * empty.
-   */
-  int _stackEnd = -1;
-
-  /**
-   * A flag indicating whether any unmatched groups were found during the parse.
-   */
-  bool _hasUnmatchedGroups = false;
-
-  /**
-   * A flag indicating whether to parse generic method comments, of the form
-   * `/*=T*/` and `/*<T>*/`.
-   */
-  bool scanGenericMethodComments = false;
-
-  /**
-   * A flag indicating whether the lazy compound assignment operators '&&=' and
-   * '||=' are enabled.
-   */
-  bool scanLazyAssignmentOperators = false;
-
-  /**
-   * Initialize a newly created scanner to scan characters from the given
-   * character [_reader].
-   */
-  Scanner.create(this._reader) {
-    _tokens = new Token.eof(-1);
-    _tail = _tokens;
-    _tokenStart = -1;
-    _lineStarts.add(0);
-  }
-
-  /**
-   * Return the first token in the token stream that was scanned.
-   */
-  Token get firstToken => _tokens.next;
-
-  /**
-   * Return `true` if any unmatched groups were found during the parse.
-   */
-  bool get hasUnmatchedGroups => _hasUnmatchedGroups;
-
-  /**
-   * Return an array containing the offsets of the first character of each line
-   * in the source code.
-   */
-  List<int> get lineStarts => _lineStarts;
-
-  /**
-   * Set whether documentation tokens should be preserved.
-   */
-  void set preserveComments(bool preserveComments) {
-    this._preserveComments = preserveComments;
-  }
-
-  /**
-   * Return the last token that was scanned.
-   */
-  Token get tail => _tail;
-
-  /**
-   * Append the given [token] to the end of the token stream being scanned. This
-   * method is intended to be used by subclasses that copy existing tokens and
-   * should not normally be used because it will fail to correctly associate any
-   * comments with the token being passed in.
-   */
-  void appendToken(Token token) {
-    _tail = _tail.setNext(token);
-  }
-
-  int bigSwitch(int next) {
-    _beginToken();
-    if (next == $cr) {
-      // '\r'
-      next = _reader.advance();
-      if (next == $lf) {
-        // '\n'
-        next = _reader.advance();
-      }
-      recordStartOfLine();
-      return next;
-    } else if (next == $lf) {
-      // '\n'
-      next = _reader.advance();
-      recordStartOfLine();
-      return next;
-    } else if (next == $tab || next == $space) {
-      // '\t' || ' '
-      return _reader.advance();
-    }
-    if (next == $r) {
-      // 'r'
-      int peek = _reader.peek();
-      if (peek == $double_quote || peek == $single_quote) {
-        // '"' || "'"
-        int start = _reader.offset;
-        return _tokenizeString(_reader.advance(), start, true);
-      }
-    }
-    if (($A <= next && next <= $Z) || ($a <= next && next <= $z)) {
-      // 'A'-'Z' || 'a'-'z'
-      return _tokenizeKeywordOrIdentifier(next, true);
-    }
-    if (next == $_ || next == $$) {
-      // '_' || '$'
-      return _tokenizeIdentifier(next, _reader.offset, true);
-    }
-    if (next == $lt) {
-      // '<'
-      return _tokenizeLessThan(next);
-    }
-    if (next == $gt) {
-      // '>'
-      return _tokenizeGreaterThan(next);
-    }
-    if (next == $equal) {
-      // '='
-      return _tokenizeEquals(next);
-    }
-    if (next == $exclamation) {
-      // '!'
-      return _tokenizeExclamation(next);
-    }
-    if (next == $plus) {
-      // '+'
-      return _tokenizePlus(next);
-    }
-    if (next == $minus) {
-      // '-'
-      return _tokenizeMinus(next);
-    }
-    if (next == $asterisk) {
-      // '*'
-      return _tokenizeMultiply(next);
-    }
-    if (next == $percent) {
-      // '%'
-      return _tokenizePercent(next);
-    }
-    if (next == $ampersand) {
-      // '&'
-      return _tokenizeAmpersand(next);
-    }
-    if (next == $bar) {
-      // '|'
-      return _tokenizeBar(next);
-    }
-    if (next == $caret) {
-      // '^'
-      return _tokenizeCaret(next);
-    }
-    if (next == $open_bracket) {
-      // '['
-      return _tokenizeOpenSquareBracket(next);
-    }
-    if (next == $tilde) {
-      // '~'
-      return _tokenizeTilde(next);
-    }
-    if (next == $backslash) {
-      // '\\'
-      _appendTokenOfType(TokenType.BACKSLASH);
-      return _reader.advance();
-    }
-    if (next == $hash) {
-      // '#'
-      return _tokenizeTag(next);
-    }
-    if (next == $open_paren) {
-      // '('
-      _appendBeginToken(TokenType.OPEN_PAREN);
-      return _reader.advance();
-    }
-    if (next == $close_paren) {
-      // ')'
-      _appendEndToken(TokenType.CLOSE_PAREN, TokenType.OPEN_PAREN);
-      return _reader.advance();
-    }
-    if (next == $comma) {
-      // ','
-      _appendTokenOfType(TokenType.COMMA);
-      return _reader.advance();
-    }
-    if (next == $colon) {
-      // ':'
-      _appendTokenOfType(TokenType.COLON);
-      return _reader.advance();
-    }
-    if (next == $semicolon) {
-      // ';'
-      _appendTokenOfType(TokenType.SEMICOLON);
-      return _reader.advance();
-    }
-    if (next == $question) {
-      // '?'
-      return _tokenizeQuestion();
-    }
-    if (next == $close_bracket) {
-      // ']'
-      _appendEndToken(
-          TokenType.CLOSE_SQUARE_BRACKET, TokenType.OPEN_SQUARE_BRACKET);
-      return _reader.advance();
-    }
-    if (next == $backquote) {
-      // '`'
-      _appendTokenOfType(TokenType.BACKPING);
-      return _reader.advance();
-    }
-    if (next == $lbrace) {
-      // '{'
-      _appendBeginToken(TokenType.OPEN_CURLY_BRACKET);
-      return _reader.advance();
-    }
-    if (next == $rbrace) {
-      // '}'
-      _appendEndToken(
-          TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
-      return _reader.advance();
-    }
-    if (next == $slash) {
-      // '/'
-      return _tokenizeSlashOrComment(next);
-    }
-    if (next == $at) {
-      // '@'
-      _appendTokenOfType(TokenType.AT);
-      return _reader.advance();
-    }
-    if (next == $double_quote || next == $single_quote) {
-      // '"' || "'"
-      return _tokenizeString(next, _reader.offset, false);
-    }
-    if (next == $dot) {
-      // '.'
-      return _tokenizeDotOrNumber(next);
-    }
-    if (next == $0) {
-      // '0'
-      return _tokenizeHexOrNumber(next);
-    }
-    if ($1 <= next && next <= $9) {
-      // '1'-'9'
-      return _tokenizeNumber(next);
-    }
-    if (next == -1) {
-      // EOF
-      return -1;
-    }
-    _reportError(ScannerErrorCode.ILLEGAL_CHARACTER, [next]);
-    return _reader.advance();
-  }
-
-  /**
-   * Record the fact that we are at the beginning of a new line in the source.
-   */
-  void recordStartOfLine() {
-    _lineStarts.add(_reader.offset);
-  }
-
-  /**
-   * Report an error at the given offset. The [errorCode] is the error code
-   * indicating the nature of the error. The [arguments] are any arguments
-   * needed to complete the error message
-   */
-  void reportError(
-      ScannerErrorCode errorCode, int offset, List<Object> arguments);
-
-  /**
-   * Record that the source begins on the given [line] and [column] at the
-   * current offset as given by the reader. Both the line and the column are
-   * one-based indexes. The line starts for lines before the given line will not
-   * be correct.
-   *
-   * This method must be invoked at most one time and must be invoked before
-   * scanning begins. The values provided must be sensible. The results are
-   * undefined if these conditions are violated.
-   */
-  void setSourceStart(int line, int column) {
-    int offset = _reader.offset;
-    if (line < 1 || column < 1 || offset < 0 || (line + column - 2) >= offset) {
-      return;
-    }
-    for (int i = 2; i < line; i++) {
-      _lineStarts.add(1);
-    }
-    _lineStarts.add(offset - column + 1);
-  }
-
-  /**
-   * Scan the source code to produce a list of tokens representing the source,
-   * and return the first token in the list of tokens that were produced.
-   */
-  Token tokenize() {
-    int next = _reader.advance();
-    while (next != -1) {
-      next = bigSwitch(next);
-    }
-    _appendEofToken();
-    return firstToken;
-  }
-
-  void _appendBeginToken(TokenType type) {
-    BeginToken token;
-    if (_firstComment == null) {
-      token = new BeginToken(type, _tokenStart);
-    } else {
-      token = new BeginToken(type, _tokenStart, _firstComment);
-      _firstComment = null;
-      _lastComment = null;
-    }
-    _tail = _tail.setNext(token);
-    _groupingStack.add(token);
-    _stackEnd++;
-  }
-
-  void _appendCommentToken(TokenType type, String value) {
-    CommentToken token = null;
-    TokenType genericComment = _matchGenericMethodCommentType(value);
-    if (genericComment != null) {
-      token = new CommentToken(genericComment, value, _tokenStart);
-    } else if (!_preserveComments) {
-      // Ignore comment tokens if client specified that it doesn't need them.
-      return;
-    } else {
-      // OK, remember comment tokens.
-      if (_isDocumentationComment(value)) {
-        token = new DocumentationCommentToken(type, value, _tokenStart);
-      } else {
-        token = new CommentToken(type, value, _tokenStart);
-      }
-    }
-    if (_firstComment == null) {
-      _firstComment = token;
-      _lastComment = _firstComment;
-    } else {
-      _lastComment = _lastComment.setNext(token);
-    }
-  }
-
-  void _appendEndToken(TokenType type, TokenType beginType) {
-    Token token;
-    if (_firstComment == null) {
-      token = new Token(type, _tokenStart);
-    } else {
-      token = new Token(type, _tokenStart, _firstComment);
-      _firstComment = null;
-      _lastComment = null;
-    }
-    _tail = _tail.setNext(token);
-    if (_stackEnd >= 0) {
-      BeginToken begin = _groupingStack[_stackEnd];
-      if (begin.type == beginType) {
-        begin.endToken = token;
-        _groupingStack.removeAt(_stackEnd--);
-      }
-    }
-  }
-
-  void _appendEofToken() {
-    Token eofToken;
-    if (_firstComment == null) {
-      eofToken = new Token.eof(_reader.offset + 1);
-    } else {
-      eofToken = new Token.eof(_reader.offset + 1, _firstComment);
-      _firstComment = null;
-      _lastComment = null;
-    }
-    // The EOF token points to itself so that there is always infinite
-    // look-ahead.
-    eofToken.setNext(eofToken);
-    _tail = _tail.setNext(eofToken);
-    if (_stackEnd >= 0) {
-      _hasUnmatchedGroups = true;
-      // TODO(brianwilkerson): Fix the ungrouped tokens?
-    }
-  }
-
-  void _appendKeywordToken(Keyword keyword) {
-    if (_firstComment == null) {
-      _tail = _tail.setNext(new KeywordToken(keyword, _tokenStart));
-    } else {
-      _tail =
-          _tail.setNext(new KeywordToken(keyword, _tokenStart, _firstComment));
-      _firstComment = null;
-      _lastComment = null;
-    }
-  }
-
-  void _appendStringToken(TokenType type, String value) {
-    if (_firstComment == null) {
-      _tail = _tail.setNext(new StringToken(type, value, _tokenStart));
-    } else {
-      _tail = _tail
-          .setNext(new StringToken(type, value, _tokenStart, _firstComment));
-      _firstComment = null;
-      _lastComment = null;
-    }
-  }
-
-  void _appendStringTokenWithOffset(TokenType type, String value, int offset) {
-    if (_firstComment == null) {
-      _tail = _tail.setNext(new StringToken(type, value, _tokenStart + offset));
-    } else {
-      _tail = _tail.setNext(
-          new StringToken(type, value, _tokenStart + offset, _firstComment));
-      _firstComment = null;
-      _lastComment = null;
-    }
-  }
-
-  void _appendTokenOfType(TokenType type) {
-    if (_firstComment == null) {
-      _tail = _tail.setNext(new Token(type, _tokenStart));
-    } else {
-      _tail = _tail.setNext(new Token(type, _tokenStart, _firstComment));
-      _firstComment = null;
-      _lastComment = null;
-    }
-  }
-
-  void _appendTokenOfTypeWithOffset(TokenType type, int offset) {
-    if (_firstComment == null) {
-      _tail = _tail.setNext(new Token(type, offset));
-    } else {
-      _tail = _tail.setNext(new Token(type, offset, _firstComment));
-      _firstComment = null;
-      _lastComment = null;
-    }
-  }
-
-  void _beginToken() {
-    _tokenStart = _reader.offset;
-  }
-
-  /**
-   * Return the beginning token corresponding to a closing brace that was found
-   * while scanning inside a string interpolation expression. Tokens that cannot
-   * be matched with the closing brace will be dropped from the stack.
-   */
-  BeginToken _findTokenMatchingClosingBraceInInterpolationExpression() {
-    while (_stackEnd >= 0) {
-      BeginToken begin = _groupingStack[_stackEnd];
-      if (begin.type == TokenType.OPEN_CURLY_BRACKET ||
-          begin.type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
-        return begin;
-      }
-      _hasUnmatchedGroups = true;
-      _groupingStack.removeAt(_stackEnd--);
-    }
-    //
-    // We should never get to this point because we wouldn't be inside a string
-    // interpolation expression unless we had previously found the start of the
-    // expression.
-    //
-    return null;
-  }
-
-  /**
-   * Checks if [value] is the start of a generic method type annotation comment.
-   *
-   * This can either be of the form `/*<T>*/` or `/*=T*/`. The token type is
-   * returned, or null if it was not a generic method comment.
-   */
-  TokenType _matchGenericMethodCommentType(String value) {
-    if (scanGenericMethodComments) {
-      // Match /*< and >*/
-      if (StringUtilities.startsWith3(value, 0, $slash, $asterisk, $lt) &&
-          StringUtilities.endsWith3(value, $gt, $asterisk, $slash)) {
-        return TokenType.GENERIC_METHOD_TYPE_LIST;
-      }
-      // Match /*=
-      if (StringUtilities.startsWith3(value, 0, $slash, $asterisk, $equal)) {
-        return TokenType.GENERIC_METHOD_TYPE_ASSIGN;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Report an error at the current offset. The [errorCode] is the error code
-   * indicating the nature of the error. The [arguments] are any arguments
-   * needed to complete the error message
-   */
-  void _reportError(ScannerErrorCode errorCode, [List<Object> arguments]) {
-    reportError(errorCode, _reader.offset, arguments);
-  }
-
-  int _select(int choice, TokenType yesType, TokenType noType) {
-    int next = _reader.advance();
-    if (next == choice) {
-      _appendTokenOfType(yesType);
-      return _reader.advance();
-    } else {
-      _appendTokenOfType(noType);
-      return next;
-    }
-  }
-
-  int _selectWithOffset(
-      int choice, TokenType yesType, TokenType noType, int offset) {
-    int next = _reader.advance();
-    if (next == choice) {
-      _appendTokenOfTypeWithOffset(yesType, offset);
-      return _reader.advance();
-    } else {
-      _appendTokenOfTypeWithOffset(noType, offset);
-      return next;
-    }
-  }
-
-  int _tokenizeAmpersand(int next) {
-    // &&= && &= &
-    next = _reader.advance();
-    if (next == $ampersand) {
-      next = _reader.advance();
-      if (scanLazyAssignmentOperators && next == $equal) {
-        _appendTokenOfType(TokenType.AMPERSAND_AMPERSAND_EQ);
-        return _reader.advance();
-      }
-      _appendTokenOfType(TokenType.AMPERSAND_AMPERSAND);
-      return next;
-    } else if (next == $equal) {
-      _appendTokenOfType(TokenType.AMPERSAND_EQ);
-      return _reader.advance();
-    } else {
-      _appendTokenOfType(TokenType.AMPERSAND);
-      return next;
-    }
-  }
-
-  int _tokenizeBar(int next) {
-    // ||= || |= |
-    next = _reader.advance();
-    if (next == $bar) {
-      next = _reader.advance();
-      if (scanLazyAssignmentOperators && next == $equal) {
-        _appendTokenOfType(TokenType.BAR_BAR_EQ);
-        return _reader.advance();
-      }
-      _appendTokenOfType(TokenType.BAR_BAR);
-      return next;
-    } else if (next == $equal) {
-      _appendTokenOfType(TokenType.BAR_EQ);
-      return _reader.advance();
-    } else {
-      _appendTokenOfType(TokenType.BAR);
-      return next;
-    }
-  }
-
-  int _tokenizeCaret(int next) =>
-      _select($equal, TokenType.CARET_EQ, TokenType.CARET);
-
-  int _tokenizeDotOrNumber(int next) {
-    int start = _reader.offset;
-    next = _reader.advance();
-    if ($0 <= next && next <= $9) {
-      return _tokenizeFractionPart(next, start);
-    } else if ($dot == next) {
-      return _select(
-          $dot, TokenType.PERIOD_PERIOD_PERIOD, TokenType.PERIOD_PERIOD);
-    } else {
-      _appendTokenOfType(TokenType.PERIOD);
-      return next;
-    }
-  }
-
-  int _tokenizeEquals(int next) {
-    // = == =>
-    next = _reader.advance();
-    if (next == $equal) {
-      _appendTokenOfType(TokenType.EQ_EQ);
-      return _reader.advance();
-    } else if (next == $gt) {
-      _appendTokenOfType(TokenType.FUNCTION);
-      return _reader.advance();
-    }
-    _appendTokenOfType(TokenType.EQ);
-    return next;
-  }
-
-  int _tokenizeExclamation(int next) {
-    // ! !=
-    next = _reader.advance();
-    if (next == $equal) {
-      _appendTokenOfType(TokenType.BANG_EQ);
-      return _reader.advance();
-    }
-    _appendTokenOfType(TokenType.BANG);
-    return next;
-  }
-
-  int _tokenizeExponent(int next) {
-    if (next == $plus || next == $minus) {
-      next = _reader.advance();
-    }
-    bool hasDigits = false;
-    while (true) {
-      if ($0 <= next && next <= $9) {
-        hasDigits = true;
-      } else {
-        if (!hasDigits) {
-          _reportError(ScannerErrorCode.MISSING_DIGIT);
-        }
-        return next;
-      }
-      next = _reader.advance();
-    }
-  }
-
-  int _tokenizeFractionPart(int next, int start) {
-    bool done = false;
-    bool hasDigit = false;
-    LOOP:
-    while (!done) {
-      if ($0 <= next && next <= $9) {
-        hasDigit = true;
-      } else if ($e == next || $E == next) {
-        hasDigit = true;
-        next = _tokenizeExponent(_reader.advance());
-        done = true;
-        continue LOOP;
-      } else {
-        done = true;
-        continue LOOP;
-      }
-      next = _reader.advance();
-    }
-    if (!hasDigit) {
-      _appendStringToken(TokenType.INT, _reader.getString(start, -2));
-      if ($dot == next) {
-        return _selectWithOffset($dot, TokenType.PERIOD_PERIOD_PERIOD,
-            TokenType.PERIOD_PERIOD, _reader.offset - 1);
-      }
-      _appendTokenOfTypeWithOffset(TokenType.PERIOD, _reader.offset - 1);
-      return bigSwitch(next);
-    }
-    _appendStringToken(
-        TokenType.DOUBLE, _reader.getString(start, next < 0 ? 0 : -1));
-    return next;
-  }
-
-  int _tokenizeGreaterThan(int next) {
-    // > >= >> >>=
-    next = _reader.advance();
-    if ($equal == next) {
-      _appendTokenOfType(TokenType.GT_EQ);
-      return _reader.advance();
-    } else if ($gt == next) {
-      next = _reader.advance();
-      if ($equal == next) {
-        _appendTokenOfType(TokenType.GT_GT_EQ);
-        return _reader.advance();
-      } else {
-        _appendTokenOfType(TokenType.GT_GT);
-        return next;
-      }
-    } else {
-      _appendTokenOfType(TokenType.GT);
-      return next;
-    }
-  }
-
-  int _tokenizeHex(int next) {
-    int start = _reader.offset - 1;
-    bool hasDigits = false;
-    while (true) {
-      next = _reader.advance();
-      if (($0 <= next && next <= $9) ||
-          ($A <= next && next <= $F) ||
-          ($a <= next && next <= $f)) {
-        hasDigits = true;
-      } else {
-        if (!hasDigits) {
-          _reportError(ScannerErrorCode.MISSING_HEX_DIGIT);
-        }
-        _appendStringToken(
-            TokenType.HEXADECIMAL, _reader.getString(start, next < 0 ? 0 : -1));
-        return next;
-      }
-    }
-  }
-
-  int _tokenizeHexOrNumber(int next) {
-    int x = _reader.peek();
-    if (x == $x || x == $X) {
-      _reader.advance();
-      return _tokenizeHex(x);
-    }
-    return _tokenizeNumber(next);
-  }
-
-  int _tokenizeIdentifier(int next, int start, bool allowDollar) {
-    while (($a <= next && next <= $z) ||
-        ($A <= next && next <= $Z) ||
-        ($0 <= next && next <= $9) ||
-        next == $_ ||
-        (next == $$ && allowDollar)) {
-      next = _reader.advance();
-    }
-    _appendStringToken(
-        TokenType.IDENTIFIER, _reader.getString(start, next < 0 ? 0 : -1));
-    return next;
-  }
-
-  int _tokenizeInterpolatedExpression(int next, int start) {
-    _appendBeginToken(TokenType.STRING_INTERPOLATION_EXPRESSION);
-    next = _reader.advance();
-    while (next != -1) {
-      if (next == $rbrace) {
-        BeginToken begin =
-            _findTokenMatchingClosingBraceInInterpolationExpression();
-        if (begin == null) {
-          _beginToken();
-          _appendTokenOfType(TokenType.CLOSE_CURLY_BRACKET);
-          next = _reader.advance();
-          _beginToken();
-          return next;
-        } else if (begin.type == TokenType.OPEN_CURLY_BRACKET) {
-          _beginToken();
-          _appendEndToken(
-              TokenType.CLOSE_CURLY_BRACKET, TokenType.OPEN_CURLY_BRACKET);
-          next = _reader.advance();
-          _beginToken();
-        } else if (begin.type == TokenType.STRING_INTERPOLATION_EXPRESSION) {
-          _beginToken();
-          _appendEndToken(TokenType.CLOSE_CURLY_BRACKET,
-              TokenType.STRING_INTERPOLATION_EXPRESSION);
-          next = _reader.advance();
-          _beginToken();
-          return next;
-        }
-      } else {
-        next = bigSwitch(next);
-      }
-    }
-    return next;
-  }
-
-  int _tokenizeInterpolatedIdentifier(int next, int start) {
-    _appendStringTokenWithOffset(
-        TokenType.STRING_INTERPOLATION_IDENTIFIER, "\$", 0);
-    if (($A <= next && next <= $Z) ||
-        ($a <= next && next <= $z) ||
-        next == $_) {
-      _beginToken();
-      next = _tokenizeKeywordOrIdentifier(next, false);
-    }
-    _beginToken();
-    return next;
-  }
-
-  int _tokenizeKeywordOrIdentifier(int next, bool allowDollar) {
-    KeywordState state = KeywordState.KEYWORD_STATE;
-    int start = _reader.offset;
-    while (state != null &&
-        (($A <= next && next <= $Z) || $a <= next && next <= $z)) {
-      state = state.next(next);
-      next = _reader.advance();
-    }
-    if (state == null || state.keyword() == null) {
-      return _tokenizeIdentifier(next, start, allowDollar);
-    }
-    if (($0 <= next && next <= $9) || next == $_ || next == $$) {
-      return _tokenizeIdentifier(next, start, allowDollar);
-    } else if (next < 128) {
-      _appendKeywordToken(state.keyword());
-      return next;
-    } else {
-      return _tokenizeIdentifier(next, start, allowDollar);
-    }
-  }
-
-  int _tokenizeLessThan(int next) {
-    // < <= << <<=
-    next = _reader.advance();
-    if ($equal == next) {
-      _appendTokenOfType(TokenType.LT_EQ);
-      return _reader.advance();
-    } else if ($lt == next) {
-      return _select($equal, TokenType.LT_LT_EQ, TokenType.LT_LT);
-    } else {
-      _appendTokenOfType(TokenType.LT);
-      return next;
-    }
-  }
-
-  int _tokenizeMinus(int next) {
-    // - -- -=
-    next = _reader.advance();
-    if (next == $minus) {
-      _appendTokenOfType(TokenType.MINUS_MINUS);
-      return _reader.advance();
-    } else if (next == $equal) {
-      _appendTokenOfType(TokenType.MINUS_EQ);
-      return _reader.advance();
-    } else {
-      _appendTokenOfType(TokenType.MINUS);
-      return next;
-    }
-  }
-
-  int _tokenizeMultiLineComment(int next) {
-    int nesting = 1;
-    next = _reader.advance();
-    while (true) {
-      if (-1 == next) {
-        _reportError(ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT);
-        _appendCommentToken(
-            TokenType.MULTI_LINE_COMMENT, _reader.getString(_tokenStart, 0));
-        return next;
-      } else if ($asterisk == next) {
-        next = _reader.advance();
-        if ($slash == next) {
-          --nesting;
-          if (0 == nesting) {
-            _appendCommentToken(TokenType.MULTI_LINE_COMMENT,
-                _reader.getString(_tokenStart, 0));
-            return _reader.advance();
-          } else {
-            next = _reader.advance();
-          }
-        }
-      } else if ($slash == next) {
-        next = _reader.advance();
-        if ($asterisk == next) {
-          next = _reader.advance();
-          ++nesting;
-        }
-      } else if (next == $cr) {
-        next = _reader.advance();
-        if (next == $lf) {
-          next = _reader.advance();
-        }
-        recordStartOfLine();
-      } else if (next == $lf) {
-        next = _reader.advance();
-        recordStartOfLine();
-      } else {
-        next = _reader.advance();
-      }
-    }
-  }
-
-  int _tokenizeMultiLineRawString(int quoteChar, int start) {
-    int next = _reader.advance();
-    outer:
-    while (next != -1) {
-      while (next != quoteChar) {
-        if (next == -1) {
-          break outer;
-        } else if (next == $cr) {
-          next = _reader.advance();
-          if (next == $lf) {
-            next = _reader.advance();
-          }
-          recordStartOfLine();
-        } else if (next == $lf) {
-          next = _reader.advance();
-          recordStartOfLine();
-        } else {
-          next = _reader.advance();
-        }
-      }
-      next = _reader.advance();
-      if (next == quoteChar) {
-        next = _reader.advance();
-        if (next == quoteChar) {
-          _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
-          return _reader.advance();
-        }
-      }
-    }
-    _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
-    _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
-    return _reader.advance();
-  }
-
-  int _tokenizeMultiLineString(int quoteChar, int start, bool raw) {
-    if (raw) {
-      return _tokenizeMultiLineRawString(quoteChar, start);
-    }
-    int next = _reader.advance();
-    while (next != -1) {
-      if (next == $$) {
-        _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
-        next = _tokenizeStringInterpolation(start);
-        _beginToken();
-        start = _reader.offset;
-        continue;
-      }
-      if (next == quoteChar) {
-        next = _reader.advance();
-        if (next == quoteChar) {
-          next = _reader.advance();
-          if (next == quoteChar) {
-            _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
-            return _reader.advance();
-          }
-        }
-        continue;
-      }
-      if (next == $backslash) {
-        next = _reader.advance();
-        if (next == -1) {
-          break;
-        }
-        if (next == $cr) {
-          next = _reader.advance();
-          if (next == $lf) {
-            next = _reader.advance();
-          }
-          recordStartOfLine();
-        } else if (next == $lf) {
-          recordStartOfLine();
-          next = _reader.advance();
-        } else {
-          next = _reader.advance();
-        }
-      } else if (next == $cr) {
-        next = _reader.advance();
-        if (next == $lf) {
-          next = _reader.advance();
-        }
-        recordStartOfLine();
-      } else if (next == $lf) {
-        recordStartOfLine();
-        next = _reader.advance();
-      } else {
-        next = _reader.advance();
-      }
-    }
-    _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
-    if (start == _reader.offset) {
-      _appendStringTokenWithOffset(TokenType.STRING, "", 1);
-    } else {
-      _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
-    }
-    return _reader.advance();
-  }
-
-  int _tokenizeMultiply(int next) =>
-      _select($equal, TokenType.STAR_EQ, TokenType.STAR);
-
-  int _tokenizeNumber(int next) {
-    int start = _reader.offset;
-    while (true) {
-      next = _reader.advance();
-      if ($0 <= next && next <= $9) {
-        continue;
-      } else if (next == $dot) {
-        return _tokenizeFractionPart(_reader.advance(), start);
-      } else if (next == $e || next == $E) {
-        return _tokenizeFractionPart(next, start);
-      } else {
-        _appendStringToken(
-            TokenType.INT, _reader.getString(start, next < 0 ? 0 : -1));
-        return next;
-      }
-    }
-  }
-
-  int _tokenizeOpenSquareBracket(int next) {
-    // [ []  []=
-    next = _reader.advance();
-    if (next == $close_bracket) {
-      return _select($equal, TokenType.INDEX_EQ, TokenType.INDEX);
-    } else {
-      _appendBeginToken(TokenType.OPEN_SQUARE_BRACKET);
-      return next;
-    }
-  }
-
-  int _tokenizePercent(int next) =>
-      _select($equal, TokenType.PERCENT_EQ, TokenType.PERCENT);
-
-  int _tokenizePlus(int next) {
-    // + ++ +=
-    next = _reader.advance();
-    if ($plus == next) {
-      _appendTokenOfType(TokenType.PLUS_PLUS);
-      return _reader.advance();
-    } else if ($equal == next) {
-      _appendTokenOfType(TokenType.PLUS_EQ);
-      return _reader.advance();
-    } else {
-      _appendTokenOfType(TokenType.PLUS);
-      return next;
-    }
-  }
-
-  int _tokenizeQuestion() {
-    // ? ?. ?? ??=
-    int next = _reader.advance();
-    if (next == $dot) {
-      // '.'
-      _appendTokenOfType(TokenType.QUESTION_PERIOD);
-      return _reader.advance();
-    } else if (next == $question) {
-      // '?'
-      next = _reader.advance();
-      if (next == $equal) {
-        // '='
-        _appendTokenOfType(TokenType.QUESTION_QUESTION_EQ);
-        return _reader.advance();
-      } else {
-        _appendTokenOfType(TokenType.QUESTION_QUESTION);
-        return next;
-      }
-    } else {
-      _appendTokenOfType(TokenType.QUESTION);
-      return next;
-    }
-  }
-
-  int _tokenizeSingleLineComment(int next) {
-    while (true) {
-      next = _reader.advance();
-      if (-1 == next) {
-        _appendCommentToken(
-            TokenType.SINGLE_LINE_COMMENT, _reader.getString(_tokenStart, 0));
-        return next;
-      } else if ($lf == next || $cr == next) {
-        _appendCommentToken(
-            TokenType.SINGLE_LINE_COMMENT, _reader.getString(_tokenStart, -1));
-        return next;
-      }
-    }
-  }
-
-  int _tokenizeSingleLineRawString(int next, int quoteChar, int start) {
-    next = _reader.advance();
-    while (next != -1) {
-      if (next == quoteChar) {
-        _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
-        return _reader.advance();
-      } else if (next == $cr || next == $lf) {
-        _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
-        _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
-        return _reader.advance();
-      }
-      next = _reader.advance();
-    }
-    _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
-    _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
-    return _reader.advance();
-  }
-
-  int _tokenizeSingleLineString(int next, int quoteChar, int start) {
-    while (next != quoteChar) {
-      if (next == $backslash) {
-        next = _reader.advance();
-      } else if (next == $$) {
-        _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
-        next = _tokenizeStringInterpolation(start);
-        _beginToken();
-        start = _reader.offset;
-        continue;
-      }
-      if (next <= $cr && (next == $lf || next == $cr || next == -1)) {
-        _reportError(ScannerErrorCode.UNTERMINATED_STRING_LITERAL);
-        if (start == _reader.offset) {
-          _appendStringTokenWithOffset(TokenType.STRING, "", 1);
-        } else if (next == -1) {
-          _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
-        } else {
-          _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
-        }
-        return _reader.advance();
-      }
-      next = _reader.advance();
-    }
-    _appendStringToken(TokenType.STRING, _reader.getString(start, 0));
-    return _reader.advance();
-  }
-
-  int _tokenizeSlashOrComment(int next) {
-    next = _reader.advance();
-    if ($asterisk == next) {
-      return _tokenizeMultiLineComment(next);
-    } else if ($slash == next) {
-      return _tokenizeSingleLineComment(next);
-    } else if ($equal == next) {
-      _appendTokenOfType(TokenType.SLASH_EQ);
-      return _reader.advance();
-    } else {
-      _appendTokenOfType(TokenType.SLASH);
-      return next;
-    }
-  }
-
-  int _tokenizeString(int next, int start, bool raw) {
-    int quoteChar = next;
-    next = _reader.advance();
-    if (quoteChar == next) {
-      next = _reader.advance();
-      if (quoteChar == next) {
-        // Multiline string.
-        return _tokenizeMultiLineString(quoteChar, start, raw);
-      } else {
-        // Empty string.
-        _appendStringToken(TokenType.STRING, _reader.getString(start, -1));
-        return next;
-      }
-    }
-    if (raw) {
-      return _tokenizeSingleLineRawString(next, quoteChar, start);
-    } else {
-      return _tokenizeSingleLineString(next, quoteChar, start);
-    }
-  }
-
-  int _tokenizeStringInterpolation(int start) {
-    _beginToken();
-    int next = _reader.advance();
-    if (next == $lbrace) {
-      return _tokenizeInterpolatedExpression(next, start);
-    } else {
-      return _tokenizeInterpolatedIdentifier(next, start);
-    }
-  }
-
-  int _tokenizeTag(int next) {
-    // # or #!.*[\n\r]
-    if (_reader.offset == 0) {
-      if (_reader.peek() == $exclamation) {
-        do {
-          next = _reader.advance();
-        } while (next != $lf && next != $cr && next > 0);
-        _appendStringToken(
-            TokenType.SCRIPT_TAG, _reader.getString(_tokenStart, 0));
-        return next;
-      }
-    }
-    _appendTokenOfType(TokenType.HASH);
-    return _reader.advance();
-  }
-
-  int _tokenizeTilde(int next) {
-    // ~ ~/ ~/=
-    next = _reader.advance();
-    if (next == $slash) {
-      return _select($equal, TokenType.TILDE_SLASH_EQ, TokenType.TILDE_SLASH);
-    } else {
-      _appendTokenOfType(TokenType.TILDE);
-      return next;
-    }
-  }
-
-  /**
-   * Checks if [value] is a single-line or multi-line comment.
-   */
-  static bool _isDocumentationComment(String value) {
-    return StringUtilities.startsWith3(value, 0, $slash, $slash, $slash) ||
-        StringUtilities.startsWith3(value, 0, $slash, $asterisk, $asterisk);
-  }
-}
diff --git a/pkg/front_end/lib/src/scanner/string_utilities.dart b/pkg/front_end/lib/src/scanner/string_utilities.dart
index 2398978b..3b5540b 100644
--- a/pkg/front_end/lib/src/scanner/string_utilities.dart
+++ b/pkg/front_end/lib/src/scanner/string_utilities.dart
@@ -7,20 +7,5 @@
 class StringUtilities {
   static Interner INTERNER = new NullInterner();
 
-  static bool endsWith3(String str, int c1, int c2, int c3) {
-    var length = str.length;
-    return length >= 3 &&
-        str.codeUnitAt(length - 3) == c1 &&
-        str.codeUnitAt(length - 2) == c2 &&
-        str.codeUnitAt(length - 1) == c3;
-  }
-
   static String intern(String string) => INTERNER.intern(string);
-
-  static bool startsWith3(String str, int start, int c1, int c2, int c3) {
-    return str.length - start >= 3 &&
-        str.codeUnitAt(start) == c1 &&
-        str.codeUnitAt(start + 1) == c2 &&
-        str.codeUnitAt(start + 2) == c3;
-  }
 }
diff --git a/pkg/front_end/lib/src/scanner/token.dart b/pkg/front_end/lib/src/scanner/token.dart
index e9e0fee..7015f5c 100644
--- a/pkg/front_end/lib/src/scanner/token.dart
+++ b/pkg/front_end/lib/src/scanner/token.dart
@@ -214,7 +214,8 @@
   static const Keyword LIBRARY = const Keyword("library", "LIBRARY",
       isBuiltIn: true, isTopLevelKeyword: true);
 
-  static const Keyword MIXIN = const Keyword("mixin", "MIXIN", isBuiltIn: true);
+  static const Keyword MIXIN =
+      const Keyword("mixin", "MIXIN", isBuiltIn: true, isTopLevelKeyword: true);
 
   static const Keyword NATIVE =
       const Keyword("native", "NATIVE", isPseudo: true);
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 2b6a9a5..0c4ff07 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -52,6 +52,7 @@
 ConstAndVar/script1: Fail
 ConstConstructorInSubclassOfMixinApplication/example: Fail
 ConstConstructorNonFinalField/example: Fail
+ConstConstructorRedirectionToNonConst/analyzerCode: Fail # The analyzer doesn't report this error.
 ConstConstructorWithNonConstSuper/example: Fail
 ConstEvalContext/analyzerCode: Fail # This is just used for displaying the context.
 ConstEvalContext/example: Fail # This is just used for displaying the context.
@@ -194,6 +195,7 @@
 IllegalSyncGeneratorVoidReturnType/analyzerCode: Fail # The analyzer doesn't report this error.
 ImplementsBeforeExtends/script: Fail
 ImplementsBeforeWith/script: Fail
+ImplementsFutureOr/analyzerCode: Fail # The analyzer doesn't report this error.
 ImplicitCallOfNonMethod/example: Fail
 ImportAfterPart/script1: Fail
 InitializerForStaticField/example: Fail
@@ -323,7 +325,6 @@
 StackOverflow/example: Fail
 StaticAfterConst/script1: Fail
 SuperAsExpression/example: Fail
-SuperAsIdentifier/analyzerCode: Fail
 SuperAsIdentifier/example: Fail
 SuperNullAware/example: Fail
 SuperclassHasNoDefaultConstructor/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index e240cc0..b428d444 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -303,6 +303,27 @@
   dart2jsCode: "*ignored*"
   script: "class A extends B implements C with D {}"
 
+ImplementsRepeated:
+  template: "'#name' can only be implemented once."
+  analyzerCode: IMPLEMENTS_REPEATED
+  dart2jsCode: "*fatal*"
+  tip: "Try removing #count of the occurrences."
+  script:
+    - >-
+      abstract class I {}
+      abstract class J {}
+      class K implements I, J, I {}
+
+ImplementsSuperClass:
+  template: "'#name' can't be used in both 'extends' and 'implements' clauses."
+  analyzerCode: IMPLEMENTS_SUPER_CLASS
+  dart2jsCode: "*fatal*"
+  tip: "Try removing one of the occurrences."
+  script:
+    - >-
+      abstract class A {}
+      class C extends A implements A {}
+
 MultipleImplements:
   template: "Each class definition can have at most one implements clause."
   tip: "Try combining all of the implements clauses into a single clause."
@@ -310,6 +331,15 @@
   dart2jsCode: "GENERIC"
   script: "class A implements B implements C, D {}"
 
+ImplementsFutureOr:
+  template: "'FutureOr' can't be used in an 'implements' clause."
+  severity: ERROR
+  dart2jsCode: "*fatal*"
+  script:
+    - >-
+      import 'dart:async';
+      class A implements FutureOr<int> {}
+
 ExpectedClassOrMixinBody:
   template: "Expected a class or mixin body, but got '#lexeme'."
   analyzerCode: MISSING_CLASS_BODY
@@ -2341,6 +2371,8 @@
 
 SuperAsIdentifier:
   template: "Expected identifier, but got 'super'."
+  analyzerCode: SUPER_AS_EXPRESSION
+  dart2jsCode: "*fatal*"
 
 SuperAsExpression:
   template: "Can't use 'super' as an expression."
@@ -2432,6 +2464,17 @@
   analyzerCode: CONST_CONSTRUCTOR_IN_SUBCLASS_OF_MIXIN_APPLICATION
   dart2jsCode: "*fatal*"
 
+ConstConstructorRedirectionToNonConst:
+  template: "A constant constructor can't call a non-constant constructor."
+  severity: ERROR
+  dart2jsCode: "*fatal*"
+  script:
+    - >-
+      class A {
+        const A.foo() : this.bar();
+        A.bar() {}
+      }
+
 AccessError:
   template: "Access error: '#name'."
 
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
index 4621b9a..cddd384 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test.dart
@@ -94,8 +94,8 @@
   void test_glb_bottom() {
     var A = _addClass(_class('A')).rawType;
     var env = _makeEnv();
-    expect(env.getGreatestLowerBound(bottomType, A), same(bottomType));
-    expect(env.getGreatestLowerBound(A, bottomType), same(bottomType));
+    expect(env.getStandardLowerBound(bottomType, A), same(bottomType));
+    expect(env.getStandardLowerBound(A, bottomType), same(bottomType));
   }
 
   void test_glb_function() {
@@ -105,30 +105,30 @@
     var env = _makeEnv();
     // GLB(() -> A, () -> B) = () -> B
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([], A), new FunctionType([], B)),
         new FunctionType([], B));
     // GLB(() -> void, (A, B) -> void) = ([A, B]) -> void
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([], voidType), new FunctionType([A, B], voidType)),
         new FunctionType([A, B], voidType, requiredParameterCount: 0));
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([A, B], voidType), new FunctionType([], voidType)),
         new FunctionType([A, B], voidType, requiredParameterCount: 0));
     // GLB((A) -> void, (B) -> void) = (A) -> void
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([A], voidType), new FunctionType([B], voidType)),
         new FunctionType([A], voidType));
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([B], voidType), new FunctionType([A], voidType)),
         new FunctionType([A], voidType));
     // GLB(({a: A}) -> void, ({b: B}) -> void) = ({a: A, b: B}) -> void
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([], voidType,
                 namedParameters: [new NamedType('a', A)]),
             new FunctionType([], voidType,
@@ -136,7 +136,7 @@
         new FunctionType([], voidType,
             namedParameters: [new NamedType('a', A), new NamedType('b', B)]));
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([], voidType,
                 namedParameters: [new NamedType('b', B)]),
             new FunctionType([], voidType,
@@ -146,7 +146,7 @@
     // GLB(({a: A, c: A}) -> void, ({b: B, d: B}) -> void)
     //     = ({a: A, b: B, c: A, d: B}) -> void
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([], voidType,
                 namedParameters: [
                   new NamedType('a', A),
@@ -167,7 +167,7 @@
     // GLB(({a: A, b: B}) -> void, ({a: B, b: A}) -> void)
     //     = ({a: A, b: A}) -> void
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([], voidType,
                 namedParameters: [
                   new NamedType('a', A),
@@ -181,7 +181,7 @@
         new FunctionType([], voidType,
             namedParameters: [new NamedType('a', A), new NamedType('b', A)]));
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([], voidType,
                 namedParameters: [
                   new NamedType('a', B),
@@ -196,7 +196,7 @@
             namedParameters: [new NamedType('a', A), new NamedType('b', A)]));
     // GLB((B, {a: A}) -> void, (B) -> void) = (B, {a: A}) -> void
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([B], voidType,
                 namedParameters: [new NamedType('a', A)]),
             new FunctionType([B], voidType)),
@@ -204,14 +204,14 @@
             namedParameters: [new NamedType('a', A)]));
     // GLB(({a: A}) -> void, (B) -> void) = bottom
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([], voidType,
                 namedParameters: [new NamedType('a', A)]),
             new FunctionType([B], voidType)),
         same(bottomType));
     // GLB(({a: A}) -> void, ([B]) -> void) = bottom
     expect(
-        env.getGreatestLowerBound(
+        env.getStandardLowerBound(
             new FunctionType([], voidType,
                 namedParameters: [new NamedType('a', A)]),
             new FunctionType([B], voidType, requiredParameterCount: 0)),
@@ -221,8 +221,8 @@
   void test_glb_identical() {
     var A = _addClass(_class('A')).rawType;
     var env = _makeEnv();
-    expect(env.getGreatestLowerBound(A, A), same(A));
-    expect(env.getGreatestLowerBound(new InterfaceType(A.classNode), A), A);
+    expect(env.getStandardLowerBound(A, A), same(A));
+    expect(env.getStandardLowerBound(new InterfaceType(A.classNode), A), A);
   }
 
   void test_glb_subtype() {
@@ -230,33 +230,33 @@
     var B =
         _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
     var env = _makeEnv();
-    expect(env.getGreatestLowerBound(A, B), same(B));
-    expect(env.getGreatestLowerBound(B, A), same(B));
+    expect(env.getStandardLowerBound(A, B), same(B));
+    expect(env.getStandardLowerBound(B, A), same(B));
   }
 
   void test_glb_top() {
     var A = _addClass(_class('A')).rawType;
     var env = _makeEnv();
-    expect(env.getGreatestLowerBound(dynamicType, A), same(A));
-    expect(env.getGreatestLowerBound(A, dynamicType), same(A));
-    expect(env.getGreatestLowerBound(objectType, A), same(A));
-    expect(env.getGreatestLowerBound(A, objectType), same(A));
-    expect(env.getGreatestLowerBound(voidType, A), same(A));
-    expect(env.getGreatestLowerBound(A, voidType), same(A));
+    expect(env.getStandardLowerBound(dynamicType, A), same(A));
+    expect(env.getStandardLowerBound(A, dynamicType), same(A));
+    expect(env.getStandardLowerBound(objectType, A), same(A));
+    expect(env.getStandardLowerBound(A, objectType), same(A));
+    expect(env.getStandardLowerBound(voidType, A), same(A));
+    expect(env.getStandardLowerBound(A, voidType), same(A));
   }
 
   void test_glb_unknown() {
     var A = _addClass(_class('A')).rawType;
     var env = _makeEnv();
-    expect(env.getGreatestLowerBound(A, unknownType), same(A));
-    expect(env.getGreatestLowerBound(unknownType, A), same(A));
+    expect(env.getStandardLowerBound(A, unknownType), same(A));
+    expect(env.getStandardLowerBound(unknownType, A), same(A));
   }
 
   void test_glb_unrelated() {
     var A = _addClass(_class('A')).rawType;
     var B = _addClass(_class('B')).rawType;
     var env = _makeEnv();
-    expect(env.getGreatestLowerBound(A, B), same(bottomType));
+    expect(env.getStandardLowerBound(A, B), same(bottomType));
   }
 
   void test_inferGenericFunctionOrType() {
@@ -364,12 +364,12 @@
       C.classNode.asThisSupertype
     ])).rawType;
     var env = _makeEnv();
-    expect(env.getLeastUpperBound(D, E), A);
+    expect(env.getStandardUpperBound(D, E), A);
   }
 
   void test_lub_commonClass() {
     var env = _makeEnv();
-    expect(env.getLeastUpperBound(_list(intType), _list(doubleType)),
+    expect(env.getStandardUpperBound(_list(intType), _list(doubleType)),
         _list(numType));
   }
 
@@ -380,43 +380,43 @@
     var env = _makeEnv();
     // LUB(() -> A, () -> B) = () -> A
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([], A), new FunctionType([], B)),
         new FunctionType([], A));
     // LUB(([A]) -> void, (A) -> void) = Function
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([A], voidType, requiredParameterCount: 0),
             new FunctionType([A], voidType)),
         functionType);
     // LUB(() -> void, (A, B) -> void) = Function
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([], voidType), new FunctionType([A, B], voidType)),
         functionType);
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([A, B], voidType), new FunctionType([], voidType)),
         functionType);
     // LUB((A) -> void, (B) -> void) = (B) -> void
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([A], voidType), new FunctionType([B], voidType)),
         new FunctionType([B], voidType));
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([B], voidType), new FunctionType([A], voidType)),
         new FunctionType([B], voidType));
     // LUB(({a: A}) -> void, ({b: B}) -> void) = () -> void
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([], voidType,
                 namedParameters: [new NamedType('a', A)]),
             new FunctionType([], voidType,
                 namedParameters: [new NamedType('b', B)])),
         new FunctionType([], voidType));
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([], voidType,
                 namedParameters: [new NamedType('b', B)]),
             new FunctionType([], voidType,
@@ -424,7 +424,7 @@
         new FunctionType([], voidType));
     // LUB(({a: A, c: A}) -> void, ({b: B, d: B}) -> void) = () -> void
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([], voidType,
                 namedParameters: [
                   new NamedType('a', A),
@@ -439,7 +439,7 @@
     // LUB(({a: A, b: B}) -> void, ({a: B, b: A}) -> void)
     //     = ({a: B, b: B}) -> void
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([], voidType,
                 namedParameters: [
                   new NamedType('a', A),
@@ -453,7 +453,7 @@
         new FunctionType([], voidType,
             namedParameters: [new NamedType('a', B), new NamedType('b', B)]));
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([], voidType,
                 namedParameters: [
                   new NamedType('a', B),
@@ -468,21 +468,21 @@
             namedParameters: [new NamedType('a', B), new NamedType('b', B)]));
     // LUB((B, {a: A}) -> void, (B) -> void) = (B) -> void
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([B], voidType,
                 namedParameters: [new NamedType('a', A)]),
             new FunctionType([B], voidType)),
         new FunctionType([B], voidType));
     // LUB(({a: A}) -> void, (B) -> void) = Function
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([], voidType,
                 namedParameters: [new NamedType('a', A)]),
             new FunctionType([B], voidType)),
         functionType);
     // GLB(({a: A}) -> void, ([B]) -> void) = () -> void
     expect(
-        env.getLeastUpperBound(
+        env.getStandardUpperBound(
             new FunctionType([], voidType,
                 namedParameters: [new NamedType('a', A)]),
             new FunctionType([B], voidType, requiredParameterCount: 0)),
@@ -492,8 +492,8 @@
   void test_lub_identical() {
     var A = _addClass(_class('A')).rawType;
     var env = _makeEnv();
-    expect(env.getLeastUpperBound(A, A), same(A));
-    expect(env.getLeastUpperBound(new InterfaceType(A.classNode), A), A);
+    expect(env.getStandardUpperBound(A, A), same(A));
+    expect(env.getStandardUpperBound(new InterfaceType(A.classNode), A), A);
   }
 
   void test_lub_sameClass() {
@@ -501,33 +501,34 @@
     var B =
         _addClass(_class('B', supertype: A.classNode.asThisSupertype)).rawType;
     var env = _makeEnv();
-    expect(env.getLeastUpperBound(_map(A, B), _map(B, A)), _map(A, A));
+    expect(env.getStandardUpperBound(_map(A, B), _map(B, A)), _map(A, A));
   }
 
   void test_lub_subtype() {
     var env = _makeEnv();
-    expect(env.getLeastUpperBound(_list(intType), _iterable(numType)),
+    expect(env.getStandardUpperBound(_list(intType), _iterable(numType)),
         _iterable(numType));
-    expect(env.getLeastUpperBound(_iterable(numType), _list(intType)),
+    expect(env.getStandardUpperBound(_iterable(numType), _list(intType)),
         _iterable(numType));
   }
 
   void test_lub_top() {
     var A = _addClass(_class('A')).rawType;
     var env = _makeEnv();
-    expect(env.getLeastUpperBound(dynamicType, A), same(dynamicType));
-    expect(env.getLeastUpperBound(A, dynamicType), same(dynamicType));
-    expect(env.getLeastUpperBound(objectType, A), same(objectType));
-    expect(env.getLeastUpperBound(A, objectType), same(objectType));
-    expect(env.getLeastUpperBound(voidType, A), same(voidType));
-    expect(env.getLeastUpperBound(A, voidType), same(voidType));
-    expect(env.getLeastUpperBound(dynamicType, objectType), same(dynamicType));
-    // TODO(paulberry): see dartbug.com/28513.
-    expect(env.getLeastUpperBound(objectType, dynamicType), same(objectType));
-    expect(env.getLeastUpperBound(dynamicType, voidType), same(dynamicType));
-    expect(env.getLeastUpperBound(voidType, dynamicType), same(dynamicType));
-    expect(env.getLeastUpperBound(objectType, voidType), same(voidType));
-    expect(env.getLeastUpperBound(voidType, objectType), same(voidType));
+    expect(env.getStandardUpperBound(dynamicType, A), same(dynamicType));
+    expect(env.getStandardUpperBound(A, dynamicType), same(dynamicType));
+    expect(env.getStandardUpperBound(objectType, A), same(objectType));
+    expect(env.getStandardUpperBound(A, objectType), same(objectType));
+    expect(env.getStandardUpperBound(voidType, A), same(voidType));
+    expect(env.getStandardUpperBound(A, voidType), same(voidType));
+    expect(
+        env.getStandardUpperBound(dynamicType, objectType), same(dynamicType));
+    expect(
+        env.getStandardUpperBound(objectType, dynamicType), same(dynamicType));
+    expect(env.getStandardUpperBound(dynamicType, voidType), same(voidType));
+    expect(env.getStandardUpperBound(voidType, dynamicType), same(voidType));
+    expect(env.getStandardUpperBound(objectType, voidType), same(voidType));
+    expect(env.getStandardUpperBound(voidType, objectType), same(voidType));
   }
 
   void test_lub_typeParameter() {
@@ -537,21 +538,21 @@
     U.parameter.bound = _list(bottomType);
     var env = _makeEnv();
     // LUB(T, T) = T
-    expect(env.getLeastUpperBound(T, T), same(T));
+    expect(env.getStandardUpperBound(T, T), same(T));
     // LUB(T, List<Bottom>) = LUB(List<Object>, List<Bottom>) = List<Object>
-    expect(env.getLeastUpperBound(T, _list(bottomType)), _list(objectType));
-    expect(env.getLeastUpperBound(_list(bottomType), T), _list(objectType));
+    expect(env.getStandardUpperBound(T, _list(bottomType)), _list(objectType));
+    expect(env.getStandardUpperBound(_list(bottomType), T), _list(objectType));
     // LUB(T, U) = LUB(List<Object>, U) = LUB(List<Object>, List<Bottom>)
     // = List<Object>
-    expect(env.getLeastUpperBound(T, U), _list(objectType));
-    expect(env.getLeastUpperBound(U, T), _list(objectType));
+    expect(env.getStandardUpperBound(T, U), _list(objectType));
+    expect(env.getStandardUpperBound(U, T), _list(objectType));
   }
 
   void test_lub_unknown() {
     var A = _addClass(_class('A')).rawType;
     var env = _makeEnv();
-    expect(env.getGreatestLowerBound(A, unknownType), same(A));
-    expect(env.getGreatestLowerBound(unknownType, A), same(A));
+    expect(env.getStandardLowerBound(A, unknownType), same(A));
+    expect(env.getStandardLowerBound(unknownType, A), same(A));
   }
 
   void test_solveTypeConstraint() {
diff --git a/pkg/front_end/test/token_test.dart b/pkg/front_end/test/token_test.dart
index b2b21b8..4b39e62 100644
--- a/pkg/front_end/test/token_test.dart
+++ b/pkg/front_end/test/token_test.dart
@@ -138,6 +138,7 @@
       Keyword.EXPORT,
       Keyword.IMPORT,
       Keyword.LIBRARY,
+      Keyword.MIXIN,
       Keyword.PART,
       Keyword.TYPEDEF,
     ]);
diff --git a/pkg/meta/lib/meta.dart b/pkg/meta/lib/meta.dart
index d59cc28..38a8283 100644
--- a/pkg/meta/lib/meta.dart
+++ b/pkg/meta/lib/meta.dart
@@ -193,13 +193,13 @@
 /// Classes in the same package as the marked class or mixin may extend,
 /// implement or mix-in the annotated class or mixin.
 ///
-/// Given a class or mixin `c`, which is annotated with this, and a class or
-/// mixin `d`, which extends, implements, or mixes in `c`, then tools, such as
+/// Given a class or mixin `C`, which is annotated with this, and a class or
+/// mixin `D`, which extends, implements, or mixes in `C`, then tools, such as
 /// the analyzer, may emit warnings if:
 ///
-/// * `c` and `d` are declared in different packages, or
-/// * `c` and `d` are declared in the same package, and `d` is not also
-/// annotated with this.
+/// * `C` and `D` are declared in different packages, or
+/// * `C` and `D` are declared in the same package, and `D` is not also
+///   annotated with this.
 const _Sealed sealed = const _Sealed();
 
 /// Used to annotate a field that is allowed to be overridden in Strong Mode.
diff --git a/pkg/pkg.status b/pkg/pkg.status
index c8f7401..3077d69 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -227,6 +227,7 @@
 analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180
 analysis_server/test/benchmarks_test: RuntimeError # Issue 32355
 analysis_server/test/integration/*: Skip # Issue 32356
+analysis_server/test/src/plugin/plugin_manager_test: Pass, Slow, RuntimeError # Issue 34231
 analyzer/test/generated/non_error_resolver_kernel_test: RuntimeError # Issue 30785
 analyzer/test/src/task/strong/checker_test: Pass, Slow
 analyzer/tool/task_dependency_graph/check_test: Slow, Pass
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index bc3f8ac..469682e 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -174,6 +174,11 @@
     emitWord(_encodeT(Opcode.kJumpIfNoAsserts, label.jumpOperand(offset)));
   }
 
+  void emitJumpIfNotZeroTypeArgs(Label label) {
+    emitWord(
+        _encodeT(Opcode.kJumpIfNotZeroTypeArgs, label.jumpOperand(offset)));
+  }
+
   void patchJump(int pos, int rt) {
     final Opcode opcode = Opcode.values[_getOpcodeAt(pos)];
     assert(isJump(opcode));
@@ -944,6 +949,10 @@
     emitWord(_encode0(Opcode.kDeoptRewind));
   }
 
+  void emitEntryFixed(int ra, int rd) {
+    emitWord(_encodeAD(Opcode.kEntryFixed, ra, rd));
+  }
+
   void emitEntryOptional(int ra, int rb, int rc) {
     emitWord(_encodeABC(Opcode.kEntryOptional, ra, rb, rc));
   }
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index 5ca0253..000d960 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -37,6 +37,12 @@
 // 10. InstanceCall1 and InstanceCall2 instructions are superseded by
 //     InstanceCall which works for any number of checked arguments.
 //
+// 11. EntryFixed instruction works like Entry. In addition, it checks number
+//     of fixed arguments.
+//
+// 12. JumpIfNotZeroTypeArgs instruction jumps if number of passed
+//     function type arguments is not zero.
+//
 
 enum Opcode {
   kTrap,
@@ -49,6 +55,7 @@
   kDrop,
   kJump,
   kJumpIfNoAsserts,
+  kJumpIfNotZeroTypeArgs,
   kReturn,
   kReturnTOS,
   kMove,
@@ -210,6 +217,7 @@
   kBooleanNegate,
   kThrow,
   kEntry,
+  kEntryFixed,
   kEntryOptional,
   kEntryOptimized,
   kFrame,
@@ -292,6 +300,8 @@
       Encoding.kT, const [Operand.tgt, Operand.none, Operand.none]),
   Opcode.kJumpIfNoAsserts: const Format(
       Encoding.kT, const [Operand.tgt, Operand.none, Operand.none]),
+  Opcode.kJumpIfNotZeroTypeArgs: const Format(
+      Encoding.kT, const [Operand.tgt, Operand.none, Operand.none]),
   Opcode.kReturn: const Format(
       Encoding.kA, const [Operand.reg, Operand.none, Operand.none]),
   Opcode.kReturnTOS: const Format(
@@ -614,6 +624,10 @@
       Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
   Opcode.kEntry: const Format(
       Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
+  Opcode.kEntryFixed: const Format(
+      Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
+  Opcode.kEntryOptional: const Format(
+      Encoding.kABC, const [Operand.imm, Operand.imm, Operand.imm]),
   Opcode.kEntryOptimized: const Format(
       Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
   Opcode.kFrame: const Format(
@@ -674,8 +688,6 @@
       Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
   Opcode.kDeoptRewind: const Format(
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
-  Opcode.kEntryOptional: const Format(
-      Encoding.kABC, const [Operand.imm, Operand.imm, Operand.imm]),
 };
 
 // Should match constant in runtime/vm/stack_frame_dbc.h.
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index cd7cc9a..19a91fe 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -716,6 +716,9 @@
   }
 
   void _genPrologue(Node node, FunctionNode function) {
+    final bool isClosure =
+        node is FunctionDeclaration || node is FunctionExpression;
+
     if (locals.hasOptionalParameters) {
       final int numOptionalPositional = function.positionalParameters.length -
           function.requiredParameterCount;
@@ -743,14 +746,13 @@
       }
 
       asm.emitFrame(locals.frameSize - locals.numParameters);
+    } else if (isClosure) {
+      asm.emitEntryFixed(locals.numParameters, locals.frameSize);
     } else {
       asm.emitEntry(locals.frameSize);
     }
     asm.emitCheckStack();
 
-    final bool isClosure =
-        node is FunctionDeclaration || node is FunctionExpression;
-
     if (isClosure) {
       asm.emitPush(locals.closureVarIndexInFrame);
       asm.emitLoadFieldTOS(cp.add(new ConstantInstanceField(closureContext)));
@@ -762,6 +764,22 @@
         assert(!(node is Procedure && node.isFactory));
         asm.emitCheckFunctionTypeArgs(function.typeParameters.length,
             locals.functionTypeArgsVarIndexInFrame);
+
+        bool hasNonDynamicDefaultTypes = function.typeParameters.any((p) =>
+            p.defaultType != null && p.defaultType != const DynamicType());
+        if (hasNonDynamicDefaultTypes) {
+          List<DartType> defaultTypes = function.typeParameters
+              .map((p) => p.defaultType ?? const DynamicType())
+              .toList();
+          assert(defaultTypes
+              .every((t) => !containsTypeVariable(t, functionTypeParameters)));
+
+          Label done = new Label();
+          asm.emitJumpIfNotZeroTypeArgs(done);
+          _genTypeArguments(defaultTypes);
+          asm.emitPopLocal(locals.functionTypeArgsVarIndexInFrame);
+          asm.bind(done);
+        }
       }
 
       if (isClosure) {
@@ -2608,7 +2626,8 @@
     }
 
     final bool result = node.positionalParameters.any((t) => t.accept(this)) ||
-        node.namedParameters.any((p) => p.type.accept(this));
+        node.namedParameters.any((p) => p.type.accept(this)) ||
+        node.returnType.accept(this);
 
     if (node.typeParameters.isNotEmpty) {
       _declaredTypeParameters.removeAll(node.typeParameters);
diff --git a/pkg/vm/lib/transformations/call_site_annotator.dart b/pkg/vm/lib/transformations/call_site_annotator.dart
index dd87e57..3d80936 100644
--- a/pkg/vm/lib/transformations/call_site_annotator.dart
+++ b/pkg/vm/lib/transformations/call_site_annotator.dart
@@ -65,9 +65,12 @@
   }
 
   // TODO(vegorov) handle setters as well.
+  // TODO(34162): We don't need to save the type here, just whether or not it's
+  // a statically-checked call.
   static bool shouldAnnotate(MethodInvocation node) =>
-      node.interfaceTarget != null &&
-      hasGenericCovariantParameters(node.interfaceTarget);
+      (node.interfaceTarget != null &&
+          hasGenericCovariantParameters(node.interfaceTarget)) ||
+      node.name.name == "call";
 
   /// Return [true] if the given list of [VariableDeclaration] contains
   /// any annotated with generic-covariant-impl.
diff --git a/pkg/vm/testcases/bytecode/asserts.dart.expect b/pkg/vm/testcases/bytecode/asserts.dart.expect
index 3f5cf69..176424f 100644
--- a/pkg/vm/testcases/bytecode/asserts.dart.expect
+++ b/pkg/vm/testcases/bytecode/asserts.dart.expect
@@ -65,7 +65,7 @@
   [7] = Null
 }
 ]static method test2(() → core::bool condition, () → core::String message) → void {
-  assert(condition.call(), message.call());
+  assert([@vm.call-site-attributes.metadata=receiverType:() → dart.core::bool] condition.call(), [@vm.call-site-attributes.metadata=receiverType:() → dart.core::String] message.call());
 }
 [@vm.bytecode=
 Bytecode {
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index 79176de..45fdde0 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -158,7 +158,7 @@
 }
 
 Closure CP#0 {
-  Entry                4
+  EntryFixed           2, 4
   CheckStack
   Push                 FP[-6]
   LoadFieldTOS         CP#1
@@ -2121,7 +2121,7 @@
 }
 
 Closure CP#1 {
-  Entry                4
+  EntryFixed           1, 4
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#2
diff --git a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
index 16c0efe..a20221a 100644
--- a/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
+++ b/pkg/vm/testcases/bytecode/bootstrapping.dart.expect
@@ -365,7 +365,7 @@
 }
 ]  static get platformScript() → dynamic {
     if(self::VMLibraryHooks::_cachedScript.{core::Object::==}(null) && !self::VMLibraryHooks::_computeScriptUri.{core::Object::==}(null)) {
-      self::VMLibraryHooks::_cachedScript = self::VMLibraryHooks::_computeScriptUri.call();
+      self::VMLibraryHooks::_cachedScript = [@vm.call-site-attributes.metadata=receiverType:dynamic] self::VMLibraryHooks::_computeScriptUri.call();
     }
     return self::VMLibraryHooks::_cachedScript;
   }
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
index 7959152..3347fd6 100644
--- a/pkg/vm/testcases/bytecode/closures.dart.expect
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -293,7 +293,7 @@
   [57] = ICData target-name 'call', arg-desc CP#49
 }
 Closure CP#12 {
-  Entry                4
+  EntryFixed           1, 4
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#1
@@ -378,7 +378,7 @@
 }
 
 Closure CP#9 {
-  Entry                5
+  EntryFixed           1, 5
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#1
@@ -421,7 +421,7 @@
 }
 
 Closure CP#0 {
-  Entry                5
+  EntryFixed           1, 5
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#1
@@ -474,13 +474,13 @@
           core::print(<core::Type>[self::A::T1, self::A::T2, self::A::foo::T3, self::A::foo::T4, T5, T6, T7, T8]);
           self::callWithArgs<self::A::T1, self::A::T2, self::A::foo::T3, self::A::foo::T4, T5, T6, T7, T8>();
         };
-        nested3.call();
+        [@vm.call-site-attributes.metadata=receiverType:() → dart.core::Null] nested3.call();
       }
-      nested2.call<self::C7, self::C8>();
-      nested2.call<core::List<self::C7>, core::List<self::C8>>();
+      [@vm.call-site-attributes.metadata=receiverType:<T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void] nested2.call<self::C7, self::C8>();
+      [@vm.call-site-attributes.metadata=receiverType:<T7 extends dart.core::Object = dynamic, T8 extends dart.core::Object = dynamic>() → void] nested2.call<core::List<self::C7>, core::List<self::C8>>();
     }
-    nested1.call<self::C5, self::C6>();
-    nested1.call<core::List<self::C5>, core::List<self::C6>>();
+    [@vm.call-site-attributes.metadata=receiverType:<T5 extends dart.core::Object = dynamic, T6 extends dart.core::Object = dynamic>() → void] nested1.call<self::C5, self::C6>();
+    [@vm.call-site-attributes.metadata=receiverType:<T5 extends dart.core::Object = dynamic, T6 extends dart.core::Object = dynamic>() → void] nested1.call<core::List<self::C5>, core::List<self::C6>>();
   }
 }
 class B extends core::Object {
@@ -638,7 +638,7 @@
   [46] = ICData target-name 'call', arg-desc CP#18
 }
 Closure CP#16 {
-  Entry                3
+  EntryFixed           1, 3
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#4
@@ -666,7 +666,7 @@
 }
 
 Closure CP#3 {
-  Entry                4
+  EntryFixed           2, 4
   CheckStack
   Push                 FP[-6]
   LoadFieldTOS         CP#4
@@ -739,7 +739,7 @@
 }
 
 Closure CP#43 {
-  Entry                3
+  EntryFixed           1, 3
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#4
@@ -768,12 +768,12 @@
               z = x.{core::num::+}(2);
               w = this.{self::B::foo}.{core::num::+}(y);
             }
-            closure2.call();
+            [@vm.call-site-attributes.metadata=receiverType:() → void] closure2.call();
             core::print(w);
           }
         };
-        closure1.call(10);
-        closure1.call(11);
+        [@vm.call-site-attributes.metadata=receiverType:(dart.core::int) → dart.core::Null] closure1.call(10);
+        [@vm.call-site-attributes.metadata=receiverType:(dart.core::int) → dart.core::Null] closure1.call(11);
         core::print(y);
         core::print(z);
       }
@@ -784,7 +784,7 @@
       () → core::Null closure3 = () → core::Null {
         this.{self::B::foo} = x;
       };
-      closure3.call();
+      [@vm.call-site-attributes.metadata=receiverType:() → dart.core::Null] closure3.call();
     }
   }
 }
@@ -954,7 +954,7 @@
   [33] = ICData target-name '+', arg-desc CP#2
 }
 Closure CP#8 {
-  Entry                2
+  EntryFixed           1, 2
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#9
@@ -972,7 +972,7 @@
 }
 
 Closure CP#25 {
-  Entry                3
+  EntryFixed           2, 3
   CheckStack
   Push                 FP[-6]
   LoadFieldTOS         CP#9
@@ -1098,7 +1098,7 @@
   [27] = StaticICData target 'dart.core::print', arg-desc CP#4
 }
 Closure CP#9 {
-  Entry                3
+  EntryFixed           1, 3
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#10
@@ -1118,7 +1118,7 @@
       () → core::Null inc = () → core::Null {
         i = i.{core::num::+}(1);
       };
-      inc.call();
+      [@vm.call-site-attributes.metadata=receiverType:() → dart.core::Null] inc.call();
       core::print(i);
     }
   }
@@ -1204,7 +1204,7 @@
   [18] = Reserved
 }
 Closure CP#5 {
-  Entry                2
+  EntryFixed           1, 2
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#6
@@ -1286,7 +1286,7 @@
   [22] = ICData target-name 'call', arg-desc CP#8
 }
 Closure CP#1 {
-  Entry                3
+  EntryFixed           2, 3
   CheckStack
   Push                 FP[-6]
   LoadFieldTOS         CP#2
@@ -1313,7 +1313,7 @@
   (core::int) → core::Null inc = (core::int y) → core::Null {
     x = x.{core::num::+}(y);
   };
-  inc.call(3);
+  [@vm.call-site-attributes.metadata=receiverType:(dart.core::int) → dart.core::Null] inc.call(3);
   return x;
 }
 [@vm.bytecode=
@@ -1549,7 +1549,7 @@
   [22] = TypeArgs [dart.core::int]
 }
 Closure CP#0 {
-  Entry                3
+  EntryFixed           2, 3
   CheckStack
   Push                 FP[-6]
   LoadFieldTOS         CP#1
diff --git a/pkg/vm/testcases/bytecode/super_calls.dart.expect b/pkg/vm/testcases/bytecode/super_calls.dart.expect
index d0e8cf4..64c96cf 100644
--- a/pkg/vm/testcases/bytecode/super_calls.dart.expect
+++ b/pkg/vm/testcases/bytecode/super_calls.dart.expect
@@ -205,7 +205,7 @@
   [6] = Null
 }
 ]  method testSuperCallViaGetter() → dynamic
-    return super.{self::Base1::bar}.call<core::int>("param");
+    return [@vm.call-site-attributes.metadata=receiverType:dynamic] super.{self::Base1::bar}.call<core::int>("param");
 [@vm.bytecode=
 Bytecode {
   Entry                1
@@ -467,7 +467,7 @@
   [14] = Null
 }
 ]  method testSuperCallViaGetter() → dynamic
-    return super.{self::Base2::bar}.call<core::int>("param");
+    return [@vm.call-site-attributes.metadata=receiverType:dynamic] super.{self::Base2::bar}.call<core::int>("param");
 [@vm.bytecode=
 Bytecode {
   Entry                1
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
index 1917977..bd7e762 100644
--- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -405,7 +405,7 @@
   [42] = EndClosureFunctionScope
 }
 Closure CP#2 {
-  Entry                6
+  EntryFixed           1, 6
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#3
@@ -443,7 +443,7 @@
 }
 
 Closure CP#31 {
-  Entry                6
+  EntryFixed           1, 6
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#3
@@ -522,7 +522,7 @@
         y = 3;
       }
     }
-    foo.call();
+    [@vm.call-site-attributes.metadata=receiverType:() → void] foo.call();
     core::print(y);
   }
   on dynamic catch(final dynamic e, final core::StackTrace st) {
@@ -934,7 +934,7 @@
   [42] = StaticICData target 'dart.core::print', arg-desc CP#7
 }
 Closure CP#12 {
-  Entry                2
+  EntryFixed           1, 2
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#13
@@ -968,7 +968,7 @@
               core::print(x);
               core::print(y);
             }
-            foo.call();
+            [@vm.call-site-attributes.metadata=receiverType:() → void] foo.call();
             continue #L4;
           }
           finally {
@@ -1103,7 +1103,7 @@
   [39] = ICData target-name 'call', arg-desc CP#5
 }
 Closure CP#2 {
-  Entry                6
+  EntryFixed           1, 6
   CheckStack
   Push                 FP[-5]
   LoadFieldTOS         CP#3
@@ -1293,7 +1293,7 @@
   }
   finally {
     core::print(x);
-    y.call();
+    [@vm.call-site-attributes.metadata=receiverType:dynamic] y.call();
   }
 }
 [@vm.bytecode=
diff --git a/pkg/vm/testcases/bytecode/type_ops.dart.expect b/pkg/vm/testcases/bytecode/type_ops.dart.expect
index c0628ce..924e681 100644
--- a/pkg/vm/testcases/bytecode/type_ops.dart.expect
+++ b/pkg/vm/testcases/bytecode/type_ops.dart.expect
@@ -324,41 +324,49 @@
   Entry                1
   CheckStack
   CheckFunctionTypeArgs 2, 0
+  JumpIfNotZeroTypeArgs L1
+  Push                 FP[-6]
+  LoadTypeArgumentsField CP#0
+  PushConstant         CP#1
+  InstantiateTypeArgumentsTOS 0, CP#2
+  PopLocal             r0
+L1:
   Push                 FP[-6]
   LoadTypeArgumentsField CP#0
   Push                 r0
-  PushConstant         CP#1
-  PushConstant         CP#2
   PushConstant         CP#3
-  AssertSubtype
   PushConstant         CP#4
-  Push                 r0
   PushConstant         CP#5
+  AssertSubtype
+  PushConstant         CP#1
+  Push                 r0
   PushConstant         CP#6
   PushConstant         CP#7
+  PushConstant         CP#8
   AssertSubtype
   Push                 FP[-5]
-  PushConstant         CP#4
+  PushConstant         CP#1
   Push                 r0
-  PushConstant         CP#8
   PushConstant         CP#9
-  AssertAssignable     0, CP#10
+  PushConstant         CP#10
+  AssertAssignable     0, CP#11
   Drop1
-  PushConstant         CP#4
+  PushConstant         CP#1
   ReturnTOS
 }
 ConstantPool {
   [0] = TypeArgumentsField #lib::E
-  [1] = Type #lib::E::foo6::T
-  [2] = Type #lib::E::P
-  [3] = String 'T'
-  [4] = Null
-  [5] = Type #lib::E::foo6::U
-  [6] = Type dart.core::List<#lib::E::foo6::T>
-  [7] = String 'U'
-  [8] = Type dart.core::Map<#lib::E::foo6::T, #lib::E::foo6::U>
-  [9] = String 'map'
-  [10] = SubtypeTestCache
+  [1] = Null
+  [2] = TypeArgs [#lib::E::P, dart.core::List<#lib::E::P>]
+  [3] = Type #lib::E::foo6::T
+  [4] = Type #lib::E::P
+  [5] = String 'T'
+  [6] = Type #lib::E::foo6::U
+  [7] = Type dart.core::List<#lib::E::foo6::T>
+  [8] = String 'U'
+  [9] = Type dart.core::Map<#lib::E::foo6::T, #lib::E::foo6::U>
+  [10] = String 'map'
+  [11] = SubtypeTestCache
 }
 ]  method foo6<generic-covariant-impl T extends self::E::P = self::E::P, U extends core::List<self::E::foo6::T> = core::List<self::E::P>>(core::Map<self::E::foo6::T, self::E::foo6::U> map) → void {}
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
index f58857b..b75afef 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
@@ -35,7 +35,7 @@
   self::foo2_a4(a4);
 }
 static method getDynamic() → dynamic
-  return self::unknown.call();
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown.call();
 static method main(core::List<core::String> args) → dynamic {
   self::foo1([@vm.inferred-type.metadata=dart.async::_Future] asy::Future::value<self::B>(new self::B::•()), new self::B::•(), [@vm.inferred-type.metadata=dart.async::_Future] asy::Future::value<self::B>(new self::B::•()), new self::B::•());
   self::foo2(self::getDynamic() as{TypeError} asy::Future<self::A>, self::getDynamic() as{TypeError} self::A, self::getDynamic() as{TypeError} asy::FutureOr<self::A>, self::getDynamic() as{TypeError} asy::FutureOr<self::A>);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
index 740d76d..a8d6be6 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
@@ -64,7 +64,7 @@
 [@vm.inferred-type.metadata=dart.core::Null?]static field core::Function unknown;
 static field core::Object field1 = [@vm.inferred-type.metadata=!] self::getValue();
 static method getDynamic() → dynamic
-  return self::unknown.call();
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown.call();
 static method getValue() → core::Object {
   self::A aa = self::getDynamic() as{TypeError} self::A;
   return [@vm.inferred-type.metadata=!] aa.{self::A::foo}();
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
index bee0c8e..9388a7d 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
@@ -33,7 +33,7 @@
 static method use2([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate i, [@vm.inferred-type.metadata=#lib::B?] self::A aa) → dynamic
   return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=#lib::T1] i.{self::Intermediate::bar}(aa);
 static method getDynamic() → dynamic
-  return self::unknown.call();
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown.call();
 static method allocateB() → dynamic {
   new self::B::•();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
index 2a40057..b6e35fd 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
@@ -59,7 +59,7 @@
 static method use3([@vm.inferred-type.metadata=#lib::Intermediate] self::Intermediate i, self::A aa) → dynamic
   return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=!] i.{self::Intermediate::bar}(aa);
 static method getDynamic() → dynamic
-  return self::unknown.call();
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown.call();
 static method allocateB() → dynamic {
   new self::B::•();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
index 55d3d4e..3fd5f9f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_dynamic_target.dart.expect
@@ -49,7 +49,7 @@
 static method use_bazz(dynamic x) → dynamic
   return [@vm.inferred-type.metadata=#lib::T3] x.bazz();
 static method getDynamic() → dynamic
-  return self::unknown.call();
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown.call();
 static method allocateA() → dynamic {
   new self::A::•();
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
index 78b259d..10fdcc6 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
@@ -51,7 +51,7 @@
 static method use2([@vm.inferred-type.metadata=#lib::DeepCaller2] self::DeepCaller2 x, [@vm.inferred-type.metadata=#lib::A?] self::A aa) → dynamic
   return [@vm.direct-call.metadata=#lib::DeepCaller2::barL1] [@vm.inferred-type.metadata=!] x.{self::DeepCaller2::barL1}(aa);
 static method getDynamic() → dynamic
-  return self::unknown.call();
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown.call();
 static method setField2([@vm.inferred-type.metadata=#lib::A] self::A aa, [@vm.inferred-type.metadata=#lib::T2] dynamic value) → void {
   [@vm.direct-call.metadata=#lib::A::field2] aa.{self::A::field2} = value;
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
index 86a3d0f..64585aa 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -113,7 +113,7 @@
 [@vm.inferred-type.metadata=#lib::D?]static field self::A dd = new self::D::•();
 [@vm.inferred-type.metadata=dart.core::Null?]static field core::Function unknown;
 static method getDynamic() → dynamic
-  return self::unknown.call();
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown.call();
 static method main(core::List<core::String> args) → dynamic {
   core::print([@vm.direct-call.metadata=#lib::B::foo??] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::foo}());
   core::print([@vm.direct-call.metadata=#lib::B::bar??] [@vm.inferred-type.metadata=#lib::T1] [@vm.inferred-type.metadata=#lib::B?] self::bb.{self::A::bar});
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
index 3ea010c..eb9c442 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
@@ -49,9 +49,9 @@
   [@vm.direct-call.metadata=#lib::T2::foo??] t0.{self::T0::foo}();
 }
 static method getDynamic() → dynamic
-  return self::unknown.call();
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown.call();
 static method use(dynamic x) → dynamic
-  return self::unknown.call(x);
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown.call(x);
 static method main(core::List<core::String> args) → dynamic {
   self::func1(self::getDynamic() as{TypeError} self::T0);
   self::use(self::func2);
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
index 1ad7392..8ef426f 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_flutter16182.dart.expect
@@ -56,7 +56,7 @@
     : super self::B2Base::•()
     ;
   method doSuperCall() → void {
-    [@vm.direct-call.metadata=#lib::A2::call] [@vm.inferred-type.metadata=#lib::A2] super.{self::B2Base::aa2}.call(1, 2, 3, 4, 5, new self::T2::•());
+    [@vm.call-site-attributes.metadata=receiverType:dynamic] [@vm.direct-call.metadata=#lib::A2::call] [@vm.inferred-type.metadata=#lib::A2] super.{self::B2Base::aa2}.call(1, 2, 3, 4, 5, new self::T2::•());
   }
 }
 class T3 extends core::Object {
@@ -127,7 +127,7 @@
   exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
 }
 static method getDynamic3() → dynamic
-  return self::unknown3.call();
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown3.call();
 static method test3() → void {
   self::getDynamic3().aa3(1, 2, 3, 4, 5, 6, new self::T3::•());
   self::ok = false;
@@ -135,7 +135,7 @@
   exp::Expect::isTrue([@vm.inferred-type.metadata=dart.core::bool?] self::ok);
 }
 static method getDynamic4() → dynamic
-  return self::unknown4.call();
+  return [@vm.call-site-attributes.metadata=receiverType:dart.core::Function] self::unknown4.call();
 static method test4() → void {
   self::getDynamic4().aa4(1, 2, 3, 4, 5, 6, 7, new self::T4::•());
   self::ok = false;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
index 8492698..871430a 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
@@ -25,5 +25,5 @@
   return new self::B::•();
 static method main(core::List<core::String> args) → dynamic {
   core::Function closure = () → self::B => new self::B::•();
-  new self::TearOffDynamicMethod::•(closure.call());
+  new self::TearOffDynamicMethod::•([@vm.call-site-attributes.metadata=receiverType:dart.core::Function] closure.call());
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
index 689ae8c..eed4b00 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
@@ -22,7 +22,7 @@
   method foo() → core::int
     return [@vm.direct-call.metadata=dart.core::_IntegerImplementation::+] [@vm.inferred-type.metadata=int?] 3.{core::num::+}([@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=int?] [@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError} core::num) as{TypeError} core::int;
   method doCall(dynamic x) → core::int
-    return x.call() as{TypeError} core::int;
+    return [@vm.call-site-attributes.metadata=receiverType:dynamic] x.call() as{TypeError} core::int;
 }
 class TearOffSuperMethod extends self::Base {
   synthetic constructor •() → void
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 3583691..96351e9 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -880,16 +880,6 @@
   executable = false
 }
 
-bin_to_linkable("platform_dill_linkable") {
-  deps = [
-    "../vm:vm_legacy_platform",
-  ]
-  input = "$root_out_dir/vm_platform.dill"
-  symbol = "kPlatformDill"
-  size_symbol = "kPlatformDillSize"
-  executable = false
-}
-
 bin_to_linkable("platform_strong_dill_linkable") {
   deps = [
     "../vm:vm_platform",
@@ -918,11 +908,9 @@
   visibility = [ ":*" ]
   deps = [
     ":kernel_service_dill_linkable",
-    ":platform_dill_linkable",
     ":platform_strong_dill_linkable",
   ]
   sources = get_target_outputs(":kernel_service_dill_linkable") +
-            get_target_outputs(":platform_dill_linkable") +
             get_target_outputs(":platform_strong_dill_linkable")
 }
 
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index b6de97c..5e58c20 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -18,15 +18,11 @@
 #if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
 extern const uint8_t kKernelServiceDill[];
 extern intptr_t kKernelServiceDillSize;
-extern const uint8_t kPlatformDill[];
-extern intptr_t kPlatformDillSize;
 extern const uint8_t kPlatformStrongDill[];
 extern intptr_t kPlatformStrongDillSize;
 #else
 const uint8_t* kKernelServiceDill = NULL;
 intptr_t kKernelServiceDillSize = 0;
-const uint8_t* kPlatformDill = NULL;
-intptr_t kPlatformDillSize = 0;
 const uint8_t* kPlatformStrongDill = NULL;
 intptr_t kPlatformStrongDillSize = 0;
 #endif  // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
@@ -42,15 +38,11 @@
 #if defined(DART_NO_SNAPSHOT) || defined(DART_PRECOMPILER)
 const uint8_t* kernel_service_dill = NULL;
 const intptr_t kernel_service_dill_size = 0;
-const uint8_t* platform_dill = NULL;
-const intptr_t platform_dill_size = 0;
 const uint8_t* platform_strong_dill = NULL;
 const intptr_t platform_strong_dill_size = 0;
 #else
 const uint8_t* kernel_service_dill = kKernelServiceDill;
 const intptr_t kernel_service_dill_size = kKernelServiceDillSize;
-const uint8_t* platform_dill = kPlatformDill;
-const intptr_t platform_dill_size = kPlatformDillSize;
 const uint8_t* platform_strong_dill = kPlatformStrongDill;
 const intptr_t platform_strong_dill_size = kPlatformStrongDillSize;
 #endif
@@ -98,7 +90,7 @@
 }
 
 void DFE::Init() {
-  if (platform_dill == NULL) {
+  if (platform_strong_dill == NULL) {
     return;
   }
 
@@ -138,19 +130,13 @@
 }
 
 void DFE::LoadPlatform(const uint8_t** kernel_buffer,
-                       intptr_t* kernel_buffer_size,
-                       bool strong) {
-  if (strong) {
-    *kernel_buffer = platform_strong_dill;
-    *kernel_buffer_size = platform_strong_dill_size;
-  } else {
-    *kernel_buffer = platform_dill;
-    *kernel_buffer_size = platform_dill_size;
-  }
+                       intptr_t* kernel_buffer_size) {
+  *kernel_buffer = platform_strong_dill;
+  *kernel_buffer_size = platform_strong_dill_size;
 }
 
 bool DFE::CanUseDartFrontend() const {
-  return (platform_dill != NULL) &&
+  return (platform_strong_dill != NULL) &&
          (KernelServiceDillAvailable() || (frontend_filename() != NULL));
 }
 
@@ -191,7 +177,6 @@
 };
 
 Dart_KernelCompilationResult DFE::CompileScript(const char* script_uri,
-                                                bool strong,
                                                 bool incremental,
                                                 const char* package_config) {
   // TODO(aam): When Frontend is ready, VM should be passing vm_outline.dill
@@ -203,12 +188,8 @@
   const char* sanitized_uri = script_uri;
 #endif
 
-  const uint8_t* platform_binary =
-      strong ? platform_strong_dill : platform_dill;
-  intptr_t platform_binary_size =
-      strong ? platform_strong_dill_size : platform_dill_size;
-  return Dart_CompileToKernel(sanitized_uri, platform_binary,
-                              platform_binary_size, incremental,
+  return Dart_CompileToKernel(sanitized_uri, platform_strong_dill,
+                              platform_strong_dill_size, incremental,
                               package_config);
 }
 
@@ -217,10 +198,9 @@
                                intptr_t* kernel_buffer_size,
                                char** error,
                                int* exit_code,
-                               bool strong,
                                const char* package_config) {
-  Dart_KernelCompilationResult result = CompileScript(
-      script_uri, strong, use_incremental_compiler(), package_config);
+  Dart_KernelCompilationResult result =
+      CompileScript(script_uri, use_incremental_compiler(), package_config);
   switch (result.status) {
     case Dart_KernelCompilationStatus_Ok:
       *kernel_buffer = result.kernel;
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index 433550f..af520658 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -57,7 +57,6 @@
   // Compiles specified script.
   // Returns result from compiling the script.
   Dart_KernelCompilationResult CompileScript(const char* script_uri,
-                                             bool strong,
                                              bool incremental,
                                              const char* package_config);
 
@@ -70,7 +69,6 @@
                             intptr_t* kernel_buffer_size,
                             char** error,
                             int* exit_code,
-                            bool strong,
                             const char* package_config);
 
   // Reads the script kernel file if specified 'script_uri' is a kernel file.
@@ -98,8 +96,7 @@
   bool CanUseDartFrontend() const;
 
   void LoadPlatform(const uint8_t** kernel_buffer,
-                    intptr_t* kernel_buffer_size,
-                    bool strong = false);
+                    intptr_t* kernel_buffer_size);
   void LoadKernelService(const uint8_t** kernel_service_buffer,
                          intptr_t* kernel_service_buffer_size);
 
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index 95bf352..b3a9074 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -702,8 +702,7 @@
           path);
     }
 
-    Dart_Handle result =
-        Extensions::LoadExtension(decoder.decoded(), path, library);
+    Dart_Handle result = Extensions::LoadExtension(lib_path, path, library);
     free(lib_path);
     return result;
   }
@@ -792,7 +791,7 @@
       uint8_t* kernel_buffer = NULL;
       intptr_t kernel_buffer_size = -1;
       dfe.CompileAndReadScript(url_string, &kernel_buffer, &kernel_buffer_size,
-                               &error, &exit_code, true /* strong */, NULL);
+                               &error, &exit_code, NULL);
       if (exit_code == 0) {
         return Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
       } else if (exit_code == kCompilationErrorExitCode) {
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index caf82ee..5531dd5 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -351,7 +351,7 @@
     intptr_t application_kernel_buffer_size = 0;
     dfe.CompileAndReadScript(script_uri, &application_kernel_buffer,
                              &application_kernel_buffer_size, error, exit_code,
-                             flags->strong, resolved_packages_config);
+                             resolved_packages_config);
     if (application_kernel_buffer == NULL) {
       Dart_ExitScope();
       Dart_ShutdownIsolate();
@@ -578,7 +578,7 @@
     // from kernel only if we can.
     const uint8_t* kernel_buffer = NULL;
     intptr_t kernel_buffer_size = 0;
-    dfe.LoadPlatform(&kernel_buffer, &kernel_buffer_size, flags->strong);
+    dfe.LoadPlatform(&kernel_buffer, &kernel_buffer_size);
     if (kernel_buffer == NULL) {
       dfe.application_kernel_buffer(&kernel_buffer, &kernel_buffer_size);
     }
@@ -699,8 +699,7 @@
   if (Options::preview_dart_2() && !isolate_run_app_snapshot) {
     const uint8_t* platform_kernel_buffer = NULL;
     intptr_t platform_kernel_buffer_size = 0;
-    dfe.LoadPlatform(&platform_kernel_buffer, &platform_kernel_buffer_size,
-                     flags->strong);
+    dfe.LoadPlatform(&platform_kernel_buffer, &platform_kernel_buffer_size);
     if (platform_kernel_buffer == NULL) {
       platform_kernel_buffer = kernel_buffer;
       platform_kernel_buffer_size = kernel_buffer_size;
@@ -971,7 +970,6 @@
     }
     if (Options::preview_dart_2()) {
       Snapshot::GenerateKernel(Options::snapshot_filename(), script_name,
-                               flags.strong,
                                isolate_data->resolved_packages_config());
     } else {
       Snapshot::GenerateScript(Options::snapshot_filename());
diff --git a/runtime/bin/snapshot_utils.cc b/runtime/bin/snapshot_utils.cc
index 7f11ffa..2ff01c2 100644
--- a/runtime/bin/snapshot_utils.cc
+++ b/runtime/bin/snapshot_utils.cc
@@ -334,7 +334,6 @@
 
 void Snapshot::GenerateKernel(const char* snapshot_filename,
                               const char* script_name,
-                              bool strong,
                               const char* package_config) {
 #if !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) && !defined(TESTING)
   uint8_t* kernel_buffer = NULL;
@@ -344,7 +343,7 @@
     WriteSnapshotFile(snapshot_filename, kernel_buffer, kernel_buffer_size);
   } else {
     Dart_KernelCompilationResult result =
-        dfe.CompileScript(script_name, strong, false, package_config);
+        dfe.CompileScript(script_name, false, package_config);
     if (result.status != Dart_KernelCompilationStatus_Ok) {
       ErrorExit(kErrorExitCode, "%s\n", result.error);
     }
diff --git a/runtime/bin/snapshot_utils.h b/runtime/bin/snapshot_utils.h
index 5f935b5..c1d6edf 100644
--- a/runtime/bin/snapshot_utils.h
+++ b/runtime/bin/snapshot_utils.h
@@ -30,7 +30,6 @@
  public:
   static void GenerateKernel(const char* snapshot_filename,
                              const char* script_name,
-                             bool strong,
                              const char* package_config);
   static void GenerateScript(const char* snapshot_filename);
   static void GenerateAppJIT(const char* snapshot_filename);
diff --git a/runtime/runtime_args.gni b/runtime/runtime_args.gni
index 91cb9cd..ba24461 100644
--- a/runtime/runtime_args.gni
+++ b/runtime/runtime_args.gni
@@ -91,7 +91,7 @@
   # We create a kernel service app-jit snapshot only for when the target
   # architecture is x64 for other cases we will use the '.dill' file
   # which is already linked in the VM.
-  if (dart_target_arch == "x64") {
+  if (dart_target_arch == "x64" && !dart_use_interpreter) {
     create_kernel_service_snapshot = true
   } else {
     create_kernel_service_snapshot = false
diff --git a/runtime/tests/vm/dart/entrypoints/tearoff.dart b/runtime/tests/vm/dart/entrypoints/tearoff.dart
new file mode 100644
index 0000000..cdebd3a
--- /dev/null
+++ b/runtime/tests/vm/dart/entrypoints/tearoff.dart
@@ -0,0 +1,37 @@
+// 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 typed calls against tearoffs go into the unchecked entrypoint.
+
+import "package:expect/expect.dart";
+import "common.dart";
+
+class C<T> {
+  @NeverInline
+  @pragma("vm:testing.unsafe.trace-entrypoints-fn", validateTearoff)
+  void target1(T x, String y) {
+    Expect.notEquals(x, -1);
+    Expect.equals(y, "foo");
+  }
+}
+
+test(List<String> args) {
+  var f = (new C<int>()).target1;
+
+  // Warmup.
+  expectedEntryPoint = -1;
+  expectedTearoffEntryPoint = -1;
+  for (int i = 0; i < 100; ++i) {
+    f(i, "foo");
+  }
+
+  expectedEntryPoint = 0;
+  expectedTearoffEntryPoint = 1;
+  const int iterations = benchmarkMode ? 100000000 : 100;
+  for (int i = 0; i < iterations; ++i) {
+    f(i, "foo");
+  }
+
+  Expect.isTrue(validateRan);
+}
diff --git a/runtime/tests/vm/dart/entrypoints/tearoff_inline_test.dart b/runtime/tests/vm/dart/entrypoints/tearoff_inline_test.dart
new file mode 100644
index 0000000..843324a
--- /dev/null
+++ b/runtime/tests/vm/dart/entrypoints/tearoff_inline_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10 -Denable_inlining=true
+
+import "tearoff.dart";
+
+main(args) => test(args);
diff --git a/runtime/tests/vm/dart/entrypoints/tearoff_noinline_test.dart b/runtime/tests/vm/dart/entrypoints/tearoff_noinline_test.dart
new file mode 100644
index 0000000..aac3f75
--- /dev/null
+++ b/runtime/tests/vm/dart/entrypoints/tearoff_noinline_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10
+
+import "tearoff.dart";
+
+main(args) => test(args);
diff --git a/runtime/tests/vm/dart/entrypoints/tearoff_prologue.dart b/runtime/tests/vm/dart/entrypoints/tearoff_prologue.dart
new file mode 100644
index 0000000..8ce9916
--- /dev/null
+++ b/runtime/tests/vm/dart/entrypoints/tearoff_prologue.dart
@@ -0,0 +1,35 @@
+// No type checks are removed here, but we can skip the argument count check.
+
+import "package:expect/expect.dart";
+import "common.dart";
+
+class C<T> {
+  @NeverInline
+  @pragma("vm:testing.unsafe.trace-entrypoints-fn", validateTearoff)
+  void samir1(T x) {
+    if (x == -1) {
+      throw "oh no";
+    }
+  }
+}
+
+test(List<String> args) {
+  var c = new C<int>();
+  var f = c.samir1;
+
+  // Warmup.
+  expectedEntryPoint = -1;
+  expectedTearoffEntryPoint = -1;
+  for (int i = 0; i < 100; ++i) {
+    f(i);
+  }
+
+  expectedEntryPoint = 0;
+  expectedTearoffEntryPoint = 1;
+  int iterations = benchmarkMode ? 100000000 : 100;
+  for (int i = 0; i < iterations; ++i) {
+    f(i);
+  }
+
+  Expect.isTrue(validateRan);
+}
diff --git a/runtime/tests/vm/dart/entrypoints/tearoff_prologue_inline_test.dart b/runtime/tests/vm/dart/entrypoints/tearoff_prologue_inline_test.dart
new file mode 100644
index 0000000..3ccf462
--- /dev/null
+++ b/runtime/tests/vm/dart/entrypoints/tearoff_prologue_inline_test.dart
@@ -0,0 +1,5 @@
+// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10 -Denable_inlining=true
+
+import "tearoff_prologue.dart";
+
+main(args) => test(args);
diff --git a/runtime/tests/vm/dart/entrypoints/tearoff_prologue_noinline_test.dart b/runtime/tests/vm/dart/entrypoints/tearoff_prologue_noinline_test.dart
new file mode 100644
index 0000000..4f1bbcd
--- /dev/null
+++ b/runtime/tests/vm/dart/entrypoints/tearoff_prologue_noinline_test.dart
@@ -0,0 +1,5 @@
+// VMOptions=--enable-testing-pragmas --no-background-compilation --enable-inlining-annotations --optimization-counter-threshold=10
+
+import "tearoff_prologue.dart";
+
+main(args) => test(args);
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 48294f4..f41388e 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -143,6 +143,9 @@
 cc/Profiler_BasicSourcePosition: Fail # http://dartbug.com/33224
 cc/Profiler_CodeTicks: Fail # dartbug.com/33337
 
+[ $arch == ia32 && $compiler != dartk && $compiler != dartkp && $compiler != dartkb && $system == windows && $runtime == vm && $mode == debug ]
+cc/BitTestImmediate: Crash # dartbug.com/34252
+
 [ $arch == x64 && $system == windows ]
 cc/Profiler_BinaryOperatorSourcePositionOptimized: Pass, Fail # Issue 31137
 cc/Profiler_ClosureAllocation: Pass, Fail # Issue 31137
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index c52f150..a8e852a 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1589,7 +1589,7 @@
   if (type.IsType() && !type.IsFunctionType() && !type.IsDartFunctionType() &&
       type.IsInstantiated()) {
     const Class& cls = Class::Handle(type.type_class());
-    return cls.IsGeneric();
+    return cls.IsGeneric() && !cls.IsFutureOrClass();
   }
 
   return false;
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 9b5a4be..d9232fa 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -1860,10 +1860,9 @@
     objects_.Add(pool);
 
     intptr_t length = pool->ptr()->length_;
-    uint8_t* entry_types = pool->ptr()->entry_types();
+    uint8_t* entry_bits = pool->ptr()->entry_bits();
     for (intptr_t i = 0; i < length; i++) {
-      ObjectPool::EntryType entry_type =
-          static_cast<ObjectPool::EntryType>(entry_types[i]);
+      auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]);
       if (entry_type == ObjectPool::kTaggedObject) {
         s->Push(pool->ptr()->data()[i].raw_obj_);
       }
@@ -1888,13 +1887,11 @@
       RawObjectPool* pool = objects_[i];
       intptr_t length = pool->ptr()->length_;
       s->WriteUnsigned(length);
-      uint8_t* entry_types = pool->ptr()->entry_types();
+      uint8_t* entry_bits = pool->ptr()->entry_bits();
       for (intptr_t j = 0; j < length; j++) {
-        ObjectPool::EntryType entry_type =
-            static_cast<ObjectPool::EntryType>(entry_types[j]);
-        s->Write<int8_t>(entry_type);
+        s->Write<uint8_t>(entry_bits[j]);
         RawObjectPool::Entry& entry = pool->ptr()->data()[j];
-        switch (entry_type) {
+        switch (ObjectPool::TypeBits::decode(entry_bits[j])) {
           case ObjectPool::kTaggedObject: {
 #if !defined(TARGET_ARCH_DBC)
             if ((entry.raw_obj_ ==
@@ -1958,11 +1955,10 @@
           pool, kObjectPoolCid, ObjectPool::InstanceSize(length), is_vm_object);
       pool->ptr()->length_ = length;
       for (intptr_t j = 0; j < length; j++) {
-        ObjectPool::EntryType entry_type =
-            static_cast<ObjectPool::EntryType>(d->Read<int8_t>());
-        pool->ptr()->entry_types()[j] = entry_type;
+        const uint8_t entry_bits = d->Read<uint8_t>();
+        pool->ptr()->entry_bits()[j] = entry_bits;
         RawObjectPool::Entry& entry = pool->ptr()->data()[j];
-        switch (entry_type) {
+        switch (ObjectPool::TypeBits::decode(entry_bits)) {
           case ObjectPool::kTaggedObject:
             entry.raw_obj_ = d->ReadRef();
             break;
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index 71c6410..e3b3919 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -85,7 +85,8 @@
 DECLARE_FLAG(int, inlining_constant_arguments_min_size_threshold);
 DECLARE_FLAG(bool, print_instruction_stats);
 
-#ifdef DART_PRECOMPILER
+#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
+    !defined(TARGET_ARCH_IA32)
 
 class DartPrecompilationPipeline : public DartCompilationPipeline {
  public:
@@ -2901,7 +2902,9 @@
 
       ASSERT(pass_state.inline_id_to_function.length() ==
              pass_state.caller_inline_id.length());
-      Assembler assembler(use_far_branches);
+
+      ObjectPoolWrapper object_pool;
+      Assembler assembler(&object_pool, use_far_branches);
 
       CodeStatistics* function_stats = NULL;
       if (FLAG_print_instruction_stats) {
@@ -3508,6 +3511,7 @@
   return result;
 }
 
-#endif  // DART_PRECOMPILER
+#endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&           \
+        // !defined(TARGET_ARCH_IA32)
 
 }  // namespace dart
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index ccbac6c..671e4bd 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -466,7 +466,8 @@
 
 typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet;
 
-#if defined(DART_PRECOMPILER)
+#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
+    !defined(TARGET_ARCH_IA32)
 // ObfuscationMap maps Strings to Strings.
 class ObfuscationMapTraits {
  public:
@@ -670,7 +671,8 @@
 
   static void Deobfuscate(Thread* thread, const GrowableObjectArray& pieces) {}
 };
-#endif  // DART_PRECOMPILER
+#endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&           \
+        // !defined(TARGET_ARCH_IA32)
 
 }  // namespace dart
 
diff --git a/runtime/vm/compiler/assembler/assembler.cc b/runtime/vm/compiler/assembler/assembler.cc
index 7b7a2ff..8c94874 100644
--- a/runtime/vm/compiler/assembler/assembler.cc
+++ b/runtime/vm/compiler/assembler/assembler.cc
@@ -228,24 +228,23 @@
 }
 
 intptr_t ObjectPoolWrapper::AddObject(const Object& obj,
-                                      Patchability patchable) {
+                                      ObjectPool::Patchability patchable) {
   ASSERT(obj.IsNotTemporaryScopedHandle());
-  return AddObject(ObjectPoolWrapperEntry(&obj), patchable);
+  return AddObject(ObjectPoolWrapperEntry(&obj, patchable));
 }
 
 intptr_t ObjectPoolWrapper::AddImmediate(uword imm) {
-  return AddObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate),
-                   kNotPatchable);
+  return AddObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate,
+                                          ObjectPool::kNotPatchable));
 }
 
-intptr_t ObjectPoolWrapper::AddObject(ObjectPoolWrapperEntry entry,
-                                      Patchability patchable) {
-  ASSERT((entry.type_ != ObjectPool::kTaggedObject) ||
+intptr_t ObjectPoolWrapper::AddObject(ObjectPoolWrapperEntry entry) {
+  ASSERT((entry.type() != ObjectPool::kTaggedObject) ||
          (entry.obj_->IsNotTemporaryScopedHandle() &&
           (entry.equivalence_ == NULL ||
            entry.equivalence_->IsNotTemporaryScopedHandle())));
   object_pool_.Add(entry);
-  if (patchable == kNotPatchable) {
+  if (entry.patchable() == ObjectPool::kNotPatchable) {
     // The object isn't patchable. Record the index for fast lookup.
     object_pool_index_table_.Insert(
         ObjIndexPair(entry, object_pool_.length() - 1));
@@ -253,47 +252,46 @@
   return object_pool_.length() - 1;
 }
 
-intptr_t ObjectPoolWrapper::FindObject(ObjectPoolWrapperEntry entry,
-                                       Patchability patchable) {
+intptr_t ObjectPoolWrapper::FindObject(ObjectPoolWrapperEntry entry) {
   // If the object is not patchable, check if we've already got it in the
   // object pool.
-  if (patchable == kNotPatchable) {
+  if (entry.patchable() == ObjectPool::kNotPatchable) {
     intptr_t idx = object_pool_index_table_.LookupValue(entry);
     if (idx != ObjIndexPair::kNoIndex) {
       return idx;
     }
   }
-  return AddObject(entry, patchable);
+  return AddObject(entry);
 }
 
 intptr_t ObjectPoolWrapper::FindObject(const Object& obj,
-                                       Patchability patchable) {
-  return FindObject(ObjectPoolWrapperEntry(&obj), patchable);
+                                       ObjectPool::Patchability patchable) {
+  return FindObject(ObjectPoolWrapperEntry(&obj, patchable));
 }
 
 intptr_t ObjectPoolWrapper::FindObject(const Object& obj,
                                        const Object& equivalence) {
-  return FindObject(ObjectPoolWrapperEntry(&obj, &equivalence), kNotPatchable);
+  return FindObject(
+      ObjectPoolWrapperEntry(&obj, &equivalence, ObjectPool::kNotPatchable));
 }
 
 intptr_t ObjectPoolWrapper::FindImmediate(uword imm) {
-  return FindObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate),
-                    kNotPatchable);
+  return FindObject(ObjectPoolWrapperEntry(imm, ObjectPool::kImmediate,
+                                           ObjectPool::kNotPatchable));
 }
 
-intptr_t ObjectPoolWrapper::FindNativeFunction(const ExternalLabel* label,
-                                               Patchability patchable) {
-  return FindObject(
-      ObjectPoolWrapperEntry(label->address(), ObjectPool::kNativeFunction),
-      patchable);
+intptr_t ObjectPoolWrapper::FindNativeFunction(
+    const ExternalLabel* label,
+    ObjectPool::Patchability patchable) {
+  return FindObject(ObjectPoolWrapperEntry(
+      label->address(), ObjectPool::kNativeFunction, patchable));
 }
 
 intptr_t ObjectPoolWrapper::FindNativeFunctionWrapper(
     const ExternalLabel* label,
-    Patchability patchable) {
-  return FindObject(ObjectPoolWrapperEntry(label->address(),
-                                           ObjectPool::kNativeFunctionWrapper),
-                    patchable);
+    ObjectPool::Patchability patchable) {
+  return FindObject(ObjectPoolWrapperEntry(
+      label->address(), ObjectPool::kNativeFunctionWrapper, patchable));
 }
 
 RawObjectPool* ObjectPoolWrapper::MakeObjectPool() {
@@ -303,8 +301,9 @@
   }
   const ObjectPool& result = ObjectPool::Handle(ObjectPool::New(len));
   for (intptr_t i = 0; i < len; ++i) {
-    ObjectPool::EntryType type = object_pool_[i].type_;
-    result.SetTypeAt(i, type);
+    auto type = object_pool_[i].type();
+    auto patchable = object_pool_[i].patchable();
+    result.SetTypeAt(i, type, patchable);
     if (type == ObjectPool::kTaggedObject) {
       result.SetObjectAt(i, *object_pool_[i].obj_);
     } else {
diff --git a/runtime/vm/compiler/assembler/assembler.h b/runtime/vm/compiler/assembler/assembler.h
index 3eddf5d..90d106d 100644
--- a/runtime/vm/compiler/assembler/assembler.h
+++ b/runtime/vm/compiler/assembler/assembler.h
@@ -285,19 +285,40 @@
 };
 
 struct ObjectPoolWrapperEntry {
-  ObjectPoolWrapperEntry() : raw_value_(), type_(), equivalence_() {}
-  explicit ObjectPoolWrapperEntry(const Object* obj)
-      : obj_(obj), type_(ObjectPool::kTaggedObject), equivalence_(obj) {}
-  explicit ObjectPoolWrapperEntry(const Object* obj, const Object* eqv)
-      : obj_(obj), type_(ObjectPool::kTaggedObject), equivalence_(eqv) {}
-  ObjectPoolWrapperEntry(uword value, ObjectPool::EntryType info)
-      : raw_value_(value), type_(info), equivalence_() {}
+  ObjectPoolWrapperEntry() : raw_value_(), entry_bits_(0), equivalence_() {}
+  ObjectPoolWrapperEntry(const Object* obj, ObjectPool::Patchability patchable)
+      : obj_(obj),
+        entry_bits_(ObjectPool::TypeBits::encode(ObjectPool::kTaggedObject) |
+                    ObjectPool::PatchableBit::encode(patchable)),
+        equivalence_(obj) {}
+  ObjectPoolWrapperEntry(const Object* obj,
+                         const Object* eqv,
+                         ObjectPool::Patchability patchable)
+      : obj_(obj),
+        entry_bits_(ObjectPool::TypeBits::encode(ObjectPool::kTaggedObject) |
+                    ObjectPool::PatchableBit::encode(patchable)),
+        equivalence_(eqv) {}
+  ObjectPoolWrapperEntry(uword value,
+                         ObjectPool::EntryType info,
+                         ObjectPool::Patchability patchable)
+      : raw_value_(value),
+        entry_bits_(ObjectPool::TypeBits::encode(info) |
+                    ObjectPool::PatchableBit::encode(patchable)),
+        equivalence_() {}
+
+  ObjectPool::EntryType type() const {
+    return ObjectPool::TypeBits::decode(entry_bits_);
+  }
+
+  ObjectPool::Patchability patchable() const {
+    return ObjectPool::PatchableBit::decode(entry_bits_);
+  }
 
   union {
     const Object* obj_;
     uword raw_value_;
   };
-  ObjectPool::EntryType type_;
+  uint8_t entry_bits_;
   const Object* equivalence_;
 };
 
@@ -312,12 +333,14 @@
   static const intptr_t kNoIndex = -1;
 
   ObjIndexPair()
-      : key_(static_cast<uword>(NULL), ObjectPool::kTaggedObject),
+      : key_(static_cast<uword>(NULL),
+             ObjectPool::kTaggedObject,
+             ObjectPool::kPatchable),
         value_(kNoIndex) {}
 
   ObjIndexPair(Key key, Value value) : value_(value) {
-    key_.type_ = key.type_;
-    if (key.type_ == ObjectPool::kTaggedObject) {
+    key_.entry_bits_ = key.entry_bits_;
+    if (key.type() == ObjectPool::kTaggedObject) {
       key_.obj_ = key.obj_;
       key_.equivalence_ = key.equivalence_;
     } else {
@@ -330,7 +353,7 @@
   static Value ValueOf(Pair kv) { return kv.value_; }
 
   static intptr_t Hashcode(Key key) {
-    if (key.type_ != ObjectPool::kTaggedObject) {
+    if (key.type() != ObjectPool::kTaggedObject) {
       return key.raw_value_;
     }
     if (key.obj_->IsSmi()) {
@@ -345,8 +368,8 @@
   }
 
   static inline bool IsKeyEqual(Pair kv, Key key) {
-    if (kv.key_.type_ != key.type_) return false;
-    if (kv.key_.type_ == ObjectPool::kTaggedObject) {
+    if (kv.key_.entry_bits_ != key.entry_bits_) return false;
+    if (kv.key_.type() == ObjectPool::kTaggedObject) {
       return (kv.key_.obj_->raw() == key.obj_->raw()) &&
              (kv.key_.equivalence_->raw() == key.equivalence_->raw());
     }
@@ -358,30 +381,27 @@
   Value value_;
 };
 
-enum Patchability {
-  kPatchable,
-  kNotPatchable,
-};
-
 class ObjectPoolWrapper : public ValueObject {
  public:
-  intptr_t AddObject(const Object& obj, Patchability patchable = kNotPatchable);
+  intptr_t AddObject(
+      const Object& obj,
+      ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
   intptr_t AddImmediate(uword imm);
-
-  intptr_t FindObject(const Object& obj,
-                      Patchability patchable = kNotPatchable);
+  intptr_t FindObject(
+      const Object& obj,
+      ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
   intptr_t FindObject(const Object& obj, const Object& equivalence);
   intptr_t FindImmediate(uword imm);
   intptr_t FindNativeFunction(const ExternalLabel* label,
-                              Patchability patchable);
+                              ObjectPool::Patchability patchable);
   intptr_t FindNativeFunctionWrapper(const ExternalLabel* label,
-                                     Patchability patchable);
+                                     ObjectPool::Patchability patchable);
 
   RawObjectPool* MakeObjectPool();
 
  private:
-  intptr_t AddObject(ObjectPoolWrapperEntry entry, Patchability patchable);
-  intptr_t FindObject(ObjectPoolWrapperEntry entry, Patchability patchable);
+  intptr_t AddObject(ObjectPoolWrapperEntry entry);
+  intptr_t FindObject(ObjectPoolWrapperEntry entry);
 
   // Objects and jump targets.
   GrowableArray<ObjectPoolWrapperEntry> object_pool_;
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 1893e92..6f6ffce 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -1377,7 +1377,7 @@
 }
 
 intptr_t Assembler::FindImmediate(int32_t imm) {
-  return object_pool_wrapper_.FindImmediate(imm);
+  return object_pool_wrapper().FindImmediate(imm);
 }
 
 // Uses a code sequence that can easily be decoded.
@@ -1480,8 +1480,8 @@
     // Make sure that class CallPattern is able to decode this load from the
     // object pool.
     const int32_t offset = ObjectPool::element_offset(
-        is_unique ? object_pool_wrapper_.AddObject(object)
-                  : object_pool_wrapper_.FindObject(object));
+        is_unique ? object_pool_wrapper().AddObject(object)
+                  : object_pool_wrapper().FindObject(object));
     LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, pp, cond);
   } else {
     UNREACHABLE();
@@ -1502,16 +1502,16 @@
                                            const Function& function,
                                            Register new_pp) {
   const int32_t offset =
-      ObjectPool::element_offset(object_pool_wrapper_.FindObject(function));
+      ObjectPool::element_offset(object_pool_wrapper().FindObject(function));
   LoadWordFromPoolOffset(dst, offset - kHeapObjectTag, new_pp, AL);
 }
 
 void Assembler::LoadNativeEntry(Register rd,
                                 const ExternalLabel* label,
-                                Patchability patchable,
+                                ObjectPool::Patchability patchable,
                                 Condition cond) {
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindNativeFunction(label, patchable));
+      object_pool_wrapper().FindNativeFunction(label, patchable));
   LoadWordFromPoolOffset(rd, offset - kHeapObjectTag, PP, cond);
 }
 
@@ -2449,40 +2449,40 @@
 }
 
 void Assembler::Branch(const StubEntry& stub_entry,
-                       Patchability patchable,
+                       ObjectPool::Patchability patchable,
                        Register pp,
                        Condition cond) {
   const Code& target_code = Code::ZoneHandle(stub_entry.code());
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target_code, patchable));
+      object_pool_wrapper().FindObject(target_code, patchable));
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, pp, cond);
   ldr(IP, FieldAddress(CODE_REG, Code::entry_point_offset()), cond);
   bx(IP, cond);
 }
 
 void Assembler::BranchLink(const Code& target,
-                           Patchability patchable,
+                           ObjectPool::Patchability patchable,
                            Code::EntryKind entry_kind) {
   // Make sure that class CallPattern is able to patch the label referred
   // to by this code sequence.
   // For added code robustness, use 'blx lr' in a patchable sequence and
   // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target, patchable));
+      object_pool_wrapper().FindObject(target, patchable));
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, PP, AL);
   ldr(LR, FieldAddress(CODE_REG, Code::entry_point_offset(entry_kind)));
   blx(LR);  // Use blx instruction so that the return branch prediction works.
 }
 
 void Assembler::BranchLink(const StubEntry& stub_entry,
-                           Patchability patchable) {
+                           ObjectPool::Patchability patchable) {
   const Code& code = Code::ZoneHandle(stub_entry.code());
   BranchLink(code, patchable);
 }
 
 void Assembler::BranchLinkPatchable(const Code& target,
                                     Code::EntryKind entry_kind) {
-  BranchLink(target, kPatchable, entry_kind);
+  BranchLink(target, ObjectPool::kPatchable, entry_kind);
 }
 
 void Assembler::BranchLinkToRuntime() {
@@ -2509,7 +2509,7 @@
   // For added code robustness, use 'blx lr' in a patchable sequence and
   // use 'blx ip' in a non-patchable sequence (see other BranchLink flavors).
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target, equivalence));
+      object_pool_wrapper().FindObject(target, equivalence));
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag, PP, AL);
   ldr(LR, FieldAddress(CODE_REG, Code::entry_point_offset(entry_kind)));
   blx(LR);  // Use blx instruction so that the return branch prediction works.
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index de2fa1f..90d554c 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -338,8 +338,10 @@
 
 class Assembler : public ValueObject {
  public:
-  explicit Assembler(bool use_far_branches = false)
+  explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
+                     bool use_far_branches = false)
       : buffer_(),
+        object_pool_wrapper_(object_pool_wrapper),
         prologue_offset_(-1),
         has_single_entry_point_(true),
         use_far_branches_(use_far_branches),
@@ -375,10 +377,10 @@
     return buffer_.pointer_offsets();
   }
 
-  ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; }
+  ObjectPoolWrapper& object_pool_wrapper() { return *object_pool_wrapper_; }
 
   RawObjectPool* MakeObjectPool() {
-    return object_pool_wrapper_.MakeObjectPool();
+    return object_pool_wrapper_->MakeObjectPool();
   }
 
   bool use_far_branches() const {
@@ -690,14 +692,15 @@
   void blx(Register rm, Condition cond = AL);
 
   void Branch(const StubEntry& stub_entry,
-              Patchability patchable = kNotPatchable,
+              ObjectPool::Patchability patchable = ObjectPool::kNotPatchable,
               Register pp = PP,
               Condition cond = AL);
 
-  void BranchLink(const StubEntry& stub_entry,
-                  Patchability patchable = kNotPatchable);
+  void BranchLink(
+      const StubEntry& stub_entry,
+      ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
   void BranchLink(const Code& code,
-                  Patchability patchable,
+                  ObjectPool::Patchability patchable,
                   Code::EntryKind entry_kind = Code::EntryKind::kNormal);
   void BranchLinkToRuntime();
 
@@ -793,7 +796,7 @@
                                   Register new_pp);
   void LoadNativeEntry(Register dst,
                        const ExternalLabel* label,
-                       Patchability patchable,
+                       ObjectPool::Patchability patchable,
                        Condition cond = AL);
   void PushObject(const Object& object);
   void CompareObject(Register rn, const Object& object);
@@ -1137,7 +1140,7 @@
 
  private:
   AssemblerBuffer buffer_;  // Contains position independent code.
-  ObjectPoolWrapper object_pool_wrapper_;
+  ObjectPoolWrapper* object_pool_wrapper_;
   int32_t prologue_offset_;
   bool has_single_entry_point_;
   bool use_far_branches_;
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index cd2b856..0d6db19 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -21,8 +21,10 @@
 
 DEFINE_FLAG(bool, use_far_branches, false, "Always use far branches");
 
-Assembler::Assembler(bool use_far_branches)
+Assembler::Assembler(ObjectPoolWrapper* object_pool_wrapper,
+                     bool use_far_branches)
     : buffer_(),
+      object_pool_wrapper_(object_pool_wrapper),
       prologue_offset_(-1),
       has_single_entry_point_(true),
       use_far_branches_(use_far_branches),
@@ -407,7 +409,7 @@
 }
 
 intptr_t Assembler::FindImmediate(int64_t imm) {
-  return object_pool_wrapper_.FindImmediate(imm);
+  return object_pool_wrapper().FindImmediate(imm);
 }
 
 bool Assembler::CanLoadFromObjectPool(const Object& object) const {
@@ -433,9 +435,9 @@
 
 void Assembler::LoadNativeEntry(Register dst,
                                 const ExternalLabel* label,
-                                Patchability patchable) {
+                                ObjectPool::Patchability patchable) {
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindNativeFunction(label, patchable));
+      object_pool_wrapper().FindNativeFunction(label, patchable));
   LoadWordFromPoolOffset(dst, offset);
 }
 
@@ -452,8 +454,8 @@
     ldr(dst, Address(THR, Thread::OffsetFromThread(object)));
   } else if (CanLoadFromObjectPool(object)) {
     const int32_t offset = ObjectPool::element_offset(
-        is_unique ? object_pool_wrapper_.AddObject(object)
-                  : object_pool_wrapper_.FindObject(object));
+        is_unique ? object_pool_wrapper().AddObject(object)
+                  : object_pool_wrapper().FindObject(object));
     LoadWordFromPoolOffset(dst, offset);
   } else {
     ASSERT(object.IsSmi());
@@ -467,7 +469,7 @@
   ASSERT(!constant_pool_allowed());
   ASSERT(new_pp != PP);
   const int32_t offset =
-      ObjectPool::element_offset(object_pool_wrapper_.FindObject(function));
+      ObjectPool::element_offset(object_pool_wrapper().FindObject(function));
   ASSERT(Address::CanHoldOffset(offset));
   ldr(dst, Address(new_pp, offset));
 }
@@ -615,31 +617,31 @@
 
 void Assembler::Branch(const StubEntry& stub_entry,
                        Register pp,
-                       Patchability patchable) {
+                       ObjectPool::Patchability patchable) {
   const Code& target = Code::ZoneHandle(stub_entry.code());
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target, patchable));
+      object_pool_wrapper().FindObject(target, patchable));
   LoadWordFromPoolOffset(CODE_REG, offset, pp);
   ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
   br(TMP);
 }
 
 void Assembler::BranchPatchable(const StubEntry& stub_entry) {
-  Branch(stub_entry, PP, kPatchable);
+  Branch(stub_entry, PP, ObjectPool::kPatchable);
 }
 
 void Assembler::BranchLink(const StubEntry& stub_entry,
-                           Patchability patchable) {
+                           ObjectPool::Patchability patchable) {
   const Code& target = Code::ZoneHandle(stub_entry.code());
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target, patchable));
+      object_pool_wrapper().FindObject(target, patchable));
   LoadWordFromPoolOffset(CODE_REG, offset);
   ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
   blr(TMP);
 }
 
 void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) {
-  BranchLink(stub_entry, kPatchable);
+  BranchLink(stub_entry, ObjectPool::kPatchable);
 }
 
 void Assembler::BranchLinkToRuntime() {
@@ -652,7 +654,7 @@
                                           const Object& equivalence) {
   const Code& target = Code::ZoneHandle(stub_entry.code());
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindObject(target, equivalence));
+      object_pool_wrapper().FindObject(target, equivalence));
   LoadWordFromPoolOffset(CODE_REG, offset);
   ldr(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
   blr(TMP);
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index bd5bb86..3cbafae 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -425,7 +425,8 @@
 
 class Assembler : public ValueObject {
  public:
-  explicit Assembler(bool use_far_branches = false);
+  explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
+                     bool use_far_branches = false);
   ~Assembler() {}
 
   void PushRegister(Register r) { Push(r); }
@@ -462,10 +463,10 @@
     return buffer_.pointer_offsets();
   }
 
-  ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; }
+  ObjectPoolWrapper& object_pool_wrapper() { return *object_pool_wrapper_; }
 
   RawObjectPool* MakeObjectPool() {
-    return object_pool_wrapper_.MakeObjectPool();
+    return object_pool_wrapper_->MakeObjectPool();
   }
 
   bool use_far_branches() const {
@@ -1374,11 +1375,12 @@
 
   void Branch(const StubEntry& stub_entry,
               Register pp,
-              Patchability patchable = kNotPatchable);
+              ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
   void BranchPatchable(const StubEntry& stub_entry);
 
-  void BranchLink(const StubEntry& stub_entry,
-                  Patchability patchable = kNotPatchable);
+  void BranchLink(
+      const StubEntry& stub_entry,
+      ObjectPool::Patchability patchable = ObjectPool::kNotPatchable);
 
   void BranchLinkPatchable(const StubEntry& stub_entry);
   void BranchLinkToRuntime();
@@ -1490,7 +1492,7 @@
   bool CanLoadFromObjectPool(const Object& object) const;
   void LoadNativeEntry(Register dst,
                        const ExternalLabel* label,
-                       Patchability patchable);
+                       ObjectPool::Patchability patchable);
   void LoadFunctionFromCalleePool(Register dst,
                                   const Function& function,
                                   Register new_pp);
@@ -1607,7 +1609,7 @@
 
  private:
   AssemblerBuffer buffer_;  // Contains position independent code.
-  ObjectPoolWrapper object_pool_wrapper_;
+  ObjectPoolWrapper* object_pool_wrapper_;
   int32_t prologue_offset_;
   bool has_single_entry_point_;
   bool use_far_branches_;
diff --git a/runtime/vm/compiler/assembler/assembler_dbc.h b/runtime/vm/compiler/assembler/assembler_dbc.h
index 45bdb9e..7642b4b7 100644
--- a/runtime/vm/compiler/assembler/assembler_dbc.h
+++ b/runtime/vm/compiler/assembler/assembler_dbc.h
@@ -27,7 +27,9 @@
 
 class Assembler : public ValueObject {
  public:
-  explicit Assembler(bool use_far_branches = false) : buffer_(), comments_() {}
+  explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
+                     bool use_far_branches = false)
+      : buffer_(), object_pool_wrapper_(object_pool_wrapper), comments_() {}
 
   ~Assembler() {}
 
@@ -48,10 +50,10 @@
     return buffer_.pointer_offsets();
   }
 
-  ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; }
+  ObjectPoolWrapper& object_pool_wrapper() { return *object_pool_wrapper_; }
 
   RawObjectPool* MakeObjectPool() {
-    return object_pool_wrapper_.MakeObjectPool();
+    return object_pool_wrapper_->MakeObjectPool();
   }
 
   void FinalizeInstructions(const MemoryRegion& region) {
@@ -124,7 +126,7 @@
 
  private:
   AssemblerBuffer buffer_;  // Contains position independent code.
-  ObjectPoolWrapper object_pool_wrapper_;
+  ObjectPoolWrapper* object_pool_wrapper_;
 
   class CodeComment : public ZoneAllocated {
    public:
diff --git a/runtime/vm/compiler/assembler/assembler_dbc_test.cc b/runtime/vm/compiler/assembler/assembler_dbc_test.cc
index ef3d7c6..fba04bd 100644
--- a/runtime/vm/compiler/assembler/assembler_dbc_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_dbc_test.cc
@@ -65,7 +65,8 @@
 
 static void MakeDummyInstanceCall(Assembler* assembler, const Object& result) {
   // Make a dummy function.
-  Assembler _assembler_;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler _assembler_(&object_pool_wrapper);
   GenerateDummyCode(&_assembler_, result);
   const char* dummy_function_name = "dummy_instance_function";
   const Function& dummy_instance_function =
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 19a00b4..1684bb6 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -223,12 +223,16 @@
 
 class Assembler : public ValueObject {
  public:
-  explicit Assembler(bool use_far_branches = false)
+  explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
+                     bool use_far_branches = false)
       : buffer_(),
         prologue_offset_(-1),
         jit_cookie_(0),
         comments_(),
         code_(Code::ZoneHandle()) {
+    // On ia32 we don't use object pools.
+    USE(object_pool_wrapper);
+
     // This mode is only needed and implemented for ARM.
     ASSERT(!use_far_branches);
   }
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index bee1638..5ce6565 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -22,8 +22,10 @@
 DECLARE_FLAG(bool, check_code_pointer);
 DECLARE_FLAG(bool, inline_alloc);
 
-Assembler::Assembler(bool use_far_branches)
+Assembler::Assembler(ObjectPoolWrapper* object_pool_wrapper,
+                     bool use_far_branches)
     : buffer_(),
+      object_pool_wrapper_(object_pool_wrapper),
       prologue_offset_(-1),
       has_single_entry_point_(true),
       comments_(),
@@ -45,9 +47,9 @@
 
 void Assembler::LoadNativeEntry(Register dst,
                                 const ExternalLabel* label,
-                                Patchability patchable) {
+                                ObjectPool::Patchability patchable) {
   const int32_t offset = ObjectPool::element_offset(
-      object_pool_wrapper_.FindNativeFunction(label, patchable));
+      object_pool_wrapper().FindNativeFunction(label, patchable));
   LoadWordFromPoolOffset(dst, offset - kHeapObjectTag);
 }
 
@@ -66,7 +68,8 @@
   ASSERT(constant_pool_allowed());
   const Code& target = Code::ZoneHandle(stub_entry.code());
   intptr_t call_start = buffer_.GetPosition();
-  const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable);
+  const intptr_t idx =
+      object_pool_wrapper().AddObject(target, ObjectPool::kPatchable);
   const int32_t offset = ObjectPool::element_offset(idx);
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
   movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset(entry_kind)));
@@ -79,7 +82,7 @@
                                     Code::EntryKind entry_kind) {
   ASSERT(constant_pool_allowed());
   const Code& target = Code::ZoneHandle(stub_entry.code());
-  const intptr_t idx = object_pool_wrapper_.FindObject(target, equivalence);
+  const intptr_t idx = object_pool_wrapper().FindObject(target, equivalence);
   const int32_t offset = ObjectPool::element_offset(idx);
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
   movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset(entry_kind)));
@@ -89,7 +92,8 @@
 void Assembler::Call(const StubEntry& stub_entry) {
   ASSERT(constant_pool_allowed());
   const Code& target = Code::ZoneHandle(stub_entry.code());
-  const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable);
+  const intptr_t idx =
+      object_pool_wrapper().FindObject(target, ObjectPool::kNotPatchable);
   const int32_t offset = ObjectPool::element_offset(idx);
   LoadWordFromPoolOffset(CODE_REG, offset - kHeapObjectTag);
   movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
@@ -464,6 +468,13 @@
   EmitUint8(imm.value() & 0xFF);
 }
 
+void Assembler::testb(const Address& address, Register reg) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitOperandREX(reg, address, REX_NONE);
+  EmitUint8(0x84);
+  EmitOperand(reg & 7, address);
+}
+
 void Assembler::testq(Register reg, const Immediate& imm) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   if (imm.is_uint8()) {
@@ -925,7 +936,8 @@
 void Assembler::JmpPatchable(const StubEntry& stub_entry, Register pp) {
   ASSERT((pp != PP) || constant_pool_allowed());
   const Code& target = Code::ZoneHandle(stub_entry.code());
-  const intptr_t idx = object_pool_wrapper_.AddObject(target, kPatchable);
+  const intptr_t idx =
+      object_pool_wrapper().AddObject(target, ObjectPool::kPatchable);
   const int32_t offset = ObjectPool::element_offset(idx);
   movq(CODE_REG, Address::AddressBaseImm32(pp, offset - kHeapObjectTag));
   movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
@@ -935,7 +947,8 @@
 void Assembler::Jmp(const StubEntry& stub_entry, Register pp) {
   ASSERT((pp != PP) || constant_pool_allowed());
   const Code& target = Code::ZoneHandle(stub_entry.code());
-  const intptr_t idx = object_pool_wrapper_.FindObject(target, kNotPatchable);
+  const intptr_t idx =
+      object_pool_wrapper().FindObject(target, ObjectPool::kNotPatchable);
   const int32_t offset = ObjectPool::element_offset(idx);
   movq(CODE_REG, FieldAddress(pp, offset));
   movq(TMP, FieldAddress(CODE_REG, Code::entry_point_offset()));
@@ -1120,8 +1133,8 @@
   if (Thread::CanLoadFromThread(object)) {
     movq(dst, Address(THR, Thread::OffsetFromThread(object)));
   } else if (CanLoadFromObjectPool(object)) {
-    const intptr_t idx = is_unique ? object_pool_wrapper_.AddObject(object)
-                                   : object_pool_wrapper_.FindObject(object);
+    const intptr_t idx = is_unique ? object_pool_wrapper().AddObject(object)
+                                   : object_pool_wrapper().FindObject(object);
     const int32_t offset = ObjectPool::element_offset(idx);
     LoadWordFromPoolOffset(dst, offset - kHeapObjectTag);
   } else {
@@ -1135,7 +1148,8 @@
                                            Register new_pp) {
   ASSERT(!constant_pool_allowed());
   ASSERT(new_pp != PP);
-  const intptr_t idx = object_pool_wrapper_.FindObject(function, kNotPatchable);
+  const intptr_t idx =
+      object_pool_wrapper().FindObject(function, ObjectPool::kNotPatchable);
   const int32_t offset = ObjectPool::element_offset(idx);
   movq(dst, Address::AddressBaseImm32(new_pp, offset - kHeapObjectTag));
 }
@@ -1183,7 +1197,8 @@
   if (Thread::CanLoadFromThread(object)) {
     cmpq(reg, Address(THR, Thread::OffsetFromThread(object)));
   } else if (CanLoadFromObjectPool(object)) {
-    const intptr_t idx = object_pool_wrapper_.FindObject(object, kNotPatchable);
+    const intptr_t idx =
+        object_pool_wrapper().FindObject(object, ObjectPool::kNotPatchable);
     const int32_t offset = ObjectPool::element_offset(idx);
     cmpq(reg, Address(PP, offset - kHeapObjectTag));
   } else {
@@ -1193,7 +1208,7 @@
 }
 
 intptr_t Assembler::FindImmediate(int64_t imm) {
-  return object_pool_wrapper_.FindImmediate(imm);
+  return object_pool_wrapper().FindImmediate(imm);
 }
 
 void Assembler::LoadImmediate(Register reg, const Immediate& imm) {
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 5b86aca..bec61ed 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -277,7 +277,8 @@
 
 class Assembler : public ValueObject {
  public:
-  explicit Assembler(bool use_far_branches = false);
+  explicit Assembler(ObjectPoolWrapper* object_pool_wrapper,
+                     bool use_far_branches = false);
 
   ~Assembler() {}
 
@@ -523,6 +524,7 @@
 
   void testl(Register reg, const Immediate& imm) { testq(reg, imm); }
   void testb(const Address& address, const Immediate& imm);
+  void testb(const Address& address, Register reg);
 
   void testq(Register reg, const Immediate& imm);
   void TestImmediate(Register dst, const Immediate& imm);
@@ -685,7 +687,7 @@
   void LoadUniqueObject(Register dst, const Object& obj);
   void LoadNativeEntry(Register dst,
                        const ExternalLabel* label,
-                       Patchability patchable);
+                       ObjectPool::Patchability patchable);
   void LoadFunctionFromCalleePool(Register dst,
                                   const Function& function,
                                   Register new_pp);
@@ -836,10 +838,10 @@
     return buffer_.pointer_offsets();
   }
 
-  ObjectPoolWrapper& object_pool_wrapper() { return object_pool_wrapper_; }
+  ObjectPoolWrapper& object_pool_wrapper() { return *object_pool_wrapper_; }
 
   RawObjectPool* MakeObjectPool() {
-    return object_pool_wrapper_.MakeObjectPool();
+    return object_pool_wrapper_->MakeObjectPool();
   }
 
   void FinalizeInstructions(const MemoryRegion& region) {
@@ -961,7 +963,7 @@
  private:
   AssemblerBuffer buffer_;
 
-  ObjectPoolWrapper object_pool_wrapper_;
+  ObjectPoolWrapper* object_pool_wrapper_;
 
   intptr_t prologue_offset_;
   bool has_single_entry_point_;
diff --git a/runtime/vm/compiler/assembler/assembler_x64_test.cc b/runtime/vm/compiler/assembler/assembler_x64_test.cc
index e478f97..a478cf7 100644
--- a/runtime/vm/compiler/assembler/assembler_x64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64_test.cc
@@ -637,6 +637,38 @@
       "ret\n");
 }
 
+ASSEMBLER_TEST_GENERATE(Testb3, assembler) {
+  Label zero;
+  __ pushq(CallingConventions::kArg1Reg);
+  __ movq(RDX, Immediate(0x10));
+  __ testb(Address(RSP, 0), RDX);
+  __ j(ZERO, &zero);
+  __ movq(RAX, Immediate(1));
+  __ popq(RCX);
+  __ ret();
+  __ Bind(&zero);
+  __ movq(RAX, Immediate(0));
+  __ popq(RCX);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(Testb3, test) {
+  typedef int (*TestbCode)(int);
+  EXPECT_EQ(1, reinterpret_cast<TestbCode>(test->entry())(0x11));
+  EXPECT_EQ(0, reinterpret_cast<TestbCode>(test->entry())(0x101));
+  EXPECT_DISASSEMBLY_NOT_WINDOWS(
+      "push rdi\n"
+      "movl rdx,0x10\n"
+      "testb rdx,[rsp]\n"
+      "jz 0x................\n"
+      "movl rax,1\n"
+      "pop rcx\n"
+      "ret\n"
+      "movl rax,0\n"
+      "pop rcx\n"
+      "ret\n");
+}
+
 ASSEMBLER_TEST_GENERATE(Increment, assembler) {
   __ movq(RAX, Immediate(0));
   __ pushq(RAX);
diff --git a/runtime/vm/compiler/assembler/disassembler_test.cc b/runtime/vm/compiler/assembler/disassembler_test.cc
index a55a3b8..86f6371 100644
--- a/runtime/vm/compiler/assembler/disassembler_test.cc
+++ b/runtime/vm/compiler/assembler/disassembler_test.cc
@@ -14,7 +14,9 @@
 #if !defined(PRODUCT) && !defined(TARGET_ARCH_DBC)
 
 TEST_CASE(Disassembler) {
-  Assembler assembler;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler assembler(&object_pool_wrapper);
+
   // The used instructions work on all platforms.
   Register reg = static_cast<Register>(0);
   assembler.PopRegister(reg);
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index dc2d982..a6f8c52 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -1407,7 +1407,7 @@
 void FlowGraph::RemoveDeadPhis(GrowableArray<PhiInstr*>* live_phis) {
   // Augment live_phis with those that have implicit real used at
   // potentially throwing instructions if there is a try-catch in this graph.
-  if (graph_entry()->SuccessorCount() > 1) {
+  if (!graph_entry()->catch_entries().is_empty()) {
     for (BlockIterator it(postorder_iterator()); !it.Done(); it.Advance()) {
       JoinEntryInstr* join = it.Current()->AsJoinEntry();
       if (join == NULL) continue;
@@ -1693,7 +1693,7 @@
     ConvertUse(it.Current(), from_rep);
   }
 
-  if (graph_entry()->SuccessorCount() > 1) {
+  if (!graph_entry()->catch_entries().is_empty()) {
     for (Value::Iterator it(def->env_use_list()); !it.Done(); it.Advance()) {
       Value* use = it.Current();
       if (use->instruction()->MayThrow() &&
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
index d79134d..8762e1b 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm.cc
@@ -765,11 +765,11 @@
   // on the call site to find out at which pool index the destination name is
   // located.
   const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
-      Object::null_object(), Patchability::kPatchable);
+      Object::null_object(), ObjectPool::Patchability::kPatchable);
   const intptr_t sub_type_cache_offset =
       ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
-  const intptr_t dst_name_index =
-      __ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
+  const intptr_t dst_name_index = __ object_pool_wrapper().AddObject(
+      dst_name, ObjectPool::Patchability::kPatchable);
   ASSERT((sub_type_cache_index + 1) == dst_name_index);
   ASSERT(__ constant_pool_allowed());
 
@@ -839,7 +839,8 @@
     }
     __ CompareImmediate(R3, GetOptimizationThreshold());
     ASSERT(function_reg == R8);
-    __ Branch(*StubCode::OptimizeFunction_entry(), kNotPatchable, new_pp, GE);
+    __ Branch(*StubCode::OptimizeFunction_entry(), ObjectPool::kNotPatchable,
+              new_pp, GE);
   }
   __ Comment("Enter frame");
   if (flow_graph().IsCompiledForOsr()) {
@@ -912,6 +913,7 @@
                                      LocationSummary* locs) {
   __ BranchLink(stub_entry);
   EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs);
+  AddStubCallTarget(Code::ZoneHandle(stub_entry.code()));
 }
 
 void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
index ddd491f..358afcf 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_arm64.cc
@@ -742,11 +742,11 @@
   // on the call site to find out at which pool index the destination name is
   // located.
   const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
-      Object::null_object(), Patchability::kPatchable);
+      Object::null_object(), ObjectPool::Patchability::kPatchable);
   const intptr_t sub_type_cache_offset =
       ObjectPool::element_offset(sub_type_cache_index);
-  const intptr_t dst_name_index =
-      __ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
+  const intptr_t dst_name_index = __ object_pool_wrapper().AddObject(
+      dst_name, ObjectPool::Patchability::kPatchable);
   ASSERT((sub_type_cache_index + 1) == dst_name_index);
   ASSERT(__ constant_pool_allowed());
 
@@ -893,6 +893,7 @@
                                      LocationSummary* locs) {
   __ BranchLink(stub_entry);
   EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs);
+  AddStubCallTarget(Code::ZoneHandle(stub_entry.code()));
 }
 
 void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
index 821d8c3..69dae4c 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_ia32.cc
@@ -852,6 +852,7 @@
                                      LocationSummary* locs) {
   __ Call(stub_entry);
   EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs);
+  AddStubCallTarget(Code::ZoneHandle(stub_entry.code()));
 }
 
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
index c96b0a1..3259e3e 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler_x64.cc
@@ -756,11 +756,11 @@
   // on the call site to find out at which pool index the destination name is
   // located.
   const intptr_t sub_type_cache_index = __ object_pool_wrapper().AddObject(
-      Object::null_object(), Patchability::kPatchable);
+      Object::null_object(), ObjectPool::Patchability::kPatchable);
   const intptr_t sub_type_cache_offset =
       ObjectPool::element_offset(sub_type_cache_index) - kHeapObjectTag;
-  const intptr_t dst_name_index =
-      __ object_pool_wrapper().AddObject(dst_name, Patchability::kPatchable);
+  const intptr_t dst_name_index = __ object_pool_wrapper().AddObject(
+      dst_name, ObjectPool::Patchability::kPatchable);
   ASSERT((sub_type_cache_index + 1) == dst_name_index);
   ASSERT(__ constant_pool_allowed());
 
@@ -902,6 +902,7 @@
                                      LocationSummary* locs) {
   __ Call(stub_entry);
   EmitCallsiteMetadata(token_pos, Thread::kNoDeoptId, kind, locs);
+  AddStubCallTarget(Code::ZoneHandle(stub_entry.code()));
 }
 
 void FlowGraphCompiler::GeneratePatchableCall(TokenPosition token_pos,
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index e4fc014..d767ec2 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -3193,12 +3193,15 @@
   ClosureCallInstr(Value* function,
                    ClosureCallNode* node,
                    PushArgumentsArray* arguments,
-                   intptr_t deopt_id)
+                   intptr_t deopt_id,
+                   Code::EntryKind entry_kind = Code::EntryKind::kNormal)
       : TemplateDartCall(deopt_id,
                          node->arguments()->type_args_len(),
                          node->arguments()->names(),
                          arguments,
-                         node->token_pos()) {
+                         node->token_pos()),
+        entry_kind_(entry_kind) {
+    ASSERT(entry_kind != Code::EntryKind::kMonomorphic);
     ASSERT(!arguments->is_empty());
     SetInputAt(0, function);
   }
@@ -3208,12 +3211,14 @@
                    intptr_t type_args_len,
                    const Array& argument_names,
                    TokenPosition token_pos,
-                   intptr_t deopt_id)
+                   intptr_t deopt_id,
+                   Code::EntryKind entry_kind = Code::EntryKind::kNormal)
       : TemplateDartCall(deopt_id,
                          type_args_len,
                          argument_names,
                          arguments,
-                         token_pos) {
+                         token_pos),
+        entry_kind_(entry_kind) {
     ASSERT(!arguments->is_empty());
     SetInputAt(0, function);
   }
@@ -3227,9 +3232,13 @@
 
   virtual bool HasUnknownSideEffects() const { return true; }
 
+  Code::EntryKind entry_kind() const { return entry_kind_; }
+
   PRINT_OPERANDS_TO_SUPPORT
 
  private:
+  const Code::EntryKind entry_kind_;
+
   DISALLOW_COPY_AND_ASSIGN(ClosureCallInstr);
 };
 
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 3d550e2..44982d3 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -265,25 +265,14 @@
   // R0: Function.
   ASSERT(locs()->in(0).reg() == R0);
   __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
-  __ ldr(R2, FieldAddress(R0, Function::entry_point_offset()));
+  __ ldr(R2, FieldAddress(R0, Code::function_entry_point_offset(entry_kind())));
 
   // R2: instructions entry point.
   // R9: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value).
   __ LoadImmediate(R9, 0);
   __ blx(R2);
-  compiler->RecordSafepoint(locs());
-  compiler->EmitCatchEntryState();
-  // Marks either the continuation point in unoptimized code or the
-  // deoptimization point in optimized code, after call.
-  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
-  if (compiler->is_optimizing()) {
-    compiler->AddDeoptIndexAtCall(deopt_id_after);
-  }
-  // Add deoptimization continuation point after the call and before the
-  // arguments are removed.
-  // In optimized code this descriptor is needed for exception handling.
-  compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after,
-                                 token_pos());
+  compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
+                                 RawPcDescriptors::kOther, locs());
   __ Drop(argument_count);
 }
 
@@ -992,7 +981,9 @@
   }
   __ LoadImmediate(R1, argc_tag);
   ExternalLabel label(entry);
-  __ LoadNativeEntry(R9, &label, link_lazily() ? kPatchable : kNotPatchable);
+  __ LoadNativeEntry(
+      R9, &label,
+      link_lazily() ? ObjectPool::kPatchable : ObjectPool::kNotPatchable);
   if (link_lazily()) {
     compiler->GeneratePatchableCall(token_pos(), *stub_entry,
                                     RawPcDescriptors::kOther, locs());
@@ -2052,7 +2043,6 @@
     compiler->SaveLiveRegisters(locs);
     compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
                            stub_entry, RawPcDescriptors::kOther, locs);
-    compiler->AddStubCallTarget(stub);
     __ MoveRegister(result_, R0);
     compiler->RestoreLiveRegisters(locs);
     __ b(exit_label());
@@ -2578,9 +2568,6 @@
       return;
     }
   }
-  const Code& stub = Code::ZoneHandle(compiler->zone(),
-                                      StubCode::AllocateArray_entry()->code());
-  compiler->AddStubCallTarget(stub);
   compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
                                   *StubCode::AllocateArray_entry(),
                                   RawPcDescriptors::kOther, locs());
@@ -2858,9 +2845,6 @@
     compiler->SaveLiveRegisters(locs);
 
     __ LoadImmediate(R1, instruction()->num_context_variables());
-    const Code& stub = Code::ZoneHandle(
-        compiler->zone(), StubCode::AllocateContext_entry()->code());
-    compiler->AddStubCallTarget(stub);
     compiler->GenerateCall(instruction()->token_pos(),
                            *StubCode::AllocateContext_entry(),
                            RawPcDescriptors::kOther, locs);
@@ -6759,7 +6743,6 @@
   const StubEntry stub_entry(stub);
   compiler->GenerateCall(token_pos(), stub_entry, RawPcDescriptors::kOther,
                          locs());
-  compiler->AddStubCallTarget(stub);
   __ Drop(ArgumentCount());  // Discard arguments.
 }
 
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index dfe94b4..6fb2171 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -268,19 +268,8 @@
   __ LoadImmediate(R5, 0);
   //??
   __ blr(R2);
-  compiler->RecordSafepoint(locs());
-  compiler->EmitCatchEntryState();
-  // Marks either the continuation point in unoptimized code or the
-  // deoptimization point in optimized code, after call.
-  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
-  if (compiler->is_optimizing()) {
-    compiler->AddDeoptIndexAtCall(deopt_id_after);
-  }
-  // Add deoptimization continuation point after the call and before the
-  // arguments are removed.
-  // In optimized code this descriptor is needed for exception handling.
-  compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after,
-                                 token_pos());
+  compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
+                                 RawPcDescriptors::kOther, locs());
   __ Drop(argument_count);
 }
 
@@ -878,7 +867,9 @@
   }
   __ LoadImmediate(R1, argc_tag);
   ExternalLabel label(entry);
-  __ LoadNativeEntry(R5, &label, link_lazily() ? kPatchable : kNotPatchable);
+  __ LoadNativeEntry(
+      R5, &label,
+      link_lazily() ? ObjectPool::kPatchable : ObjectPool::kNotPatchable);
   if (link_lazily()) {
     compiler->GeneratePatchableCall(token_pos(), *stub_entry,
                                     RawPcDescriptors::kOther, locs());
@@ -1877,7 +1868,6 @@
     compiler->SaveLiveRegisters(locs);
     compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
                            stub_entry, RawPcDescriptors::kOther, locs);
-    compiler->AddStubCallTarget(stub);
     __ mov(result_, R0);
     compiler->RestoreLiveRegisters(locs);
     __ b(exit_label());
@@ -2280,9 +2270,6 @@
       return;
     }
   }
-  const Code& stub = Code::ZoneHandle(compiler->zone(),
-                                      StubCode::AllocateArray_entry()->code());
-  compiler->AddStubCallTarget(stub);
   compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
                                   *StubCode::AllocateArray_entry(),
                                   RawPcDescriptors::kOther, locs());
@@ -2552,9 +2539,6 @@
     compiler->SaveLiveRegisters(locs);
 
     __ LoadImmediate(R1, instruction()->num_context_variables());
-    const Code& stub = Code::ZoneHandle(
-        compiler->zone(), StubCode::AllocateContext_entry()->code());
-    compiler->AddStubCallTarget(stub);
     compiler->GenerateCall(instruction()->token_pos(),
                            *StubCode::AllocateContext_entry(),
                            RawPcDescriptors::kOther, locs);
@@ -6002,7 +5986,6 @@
   const StubEntry stub_entry(stub);
   compiler->GenerateCall(token_pos(), stub_entry, RawPcDescriptors::kOther,
                          locs());
-  compiler->AddStubCallTarget(stub);
   __ Drop(ArgumentCount());  // Discard arguments.
 }
 
diff --git a/runtime/vm/compiler/backend/il_dbc.cc b/runtime/vm/compiler/backend/il_dbc.cc
index 848346f..ec66ff9 100644
--- a/runtime/vm/compiler/backend/il_dbc.cc
+++ b/runtime/vm/compiler/backend/il_dbc.cc
@@ -981,11 +981,11 @@
 
   const ExternalLabel trampoline_label(reinterpret_cast<uword>(trampoline));
   const intptr_t trampoline_kidx =
-      __ object_pool_wrapper().FindNativeFunctionWrapper(&trampoline_label,
-                                                         kPatchable);
+      __ object_pool_wrapper().FindNativeFunctionWrapper(
+          &trampoline_label, ObjectPool::kPatchable);
   const ExternalLabel label(reinterpret_cast<uword>(function));
-  const intptr_t target_kidx =
-      __ object_pool_wrapper().FindNativeFunction(&label, kPatchable);
+  const intptr_t target_kidx = __ object_pool_wrapper().FindNativeFunction(
+      &label, ObjectPool::kPatchable);
   const intptr_t argc_tag_kidx =
       __ object_pool_wrapper().FindImmediate(static_cast<uword>(argc_tag));
   __ NativeCall(trampoline_kidx, target_kidx, argc_tag_kidx);
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index b6d4586..e6d79eb 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -1744,7 +1744,6 @@
     compiler->SaveLiveRegisters(locs);
     compiler->GenerateCall(TokenPosition::kNoSource, stub_entry,
                            RawPcDescriptors::kOther, locs);
-    compiler->AddStubCallTarget(stub);
     __ MoveRegister(result_, EAX);
     compiler->RestoreLiveRegisters(locs);
     __ jmp(exit_label());
@@ -2146,9 +2145,6 @@
   }
 
   __ Bind(&slow_path);
-  const Code& stub = Code::ZoneHandle(compiler->zone(),
-                                      StubCode::AllocateArray_entry()->code());
-  compiler->AddStubCallTarget(stub);
   compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
                                   *StubCode::AllocateArray_entry(),
                                   RawPcDescriptors::kOther, locs());
@@ -2422,9 +2418,6 @@
     compiler->SaveLiveRegisters(locs);
 
     __ movl(EDX, Immediate(instruction()->num_context_variables()));
-    const Code& stub = Code::ZoneHandle(
-        compiler->zone(), StubCode::AllocateContext_entry()->code());
-    compiler->AddStubCallTarget(stub);
     compiler->GenerateCall(instruction()->token_pos(),
                            *StubCode::AllocateContext_entry(),
                            RawPcDescriptors::kOther, locs);
@@ -6147,18 +6140,8 @@
   // ECX: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value).
   __ xorl(ECX, ECX);
   __ call(EBX);
-  compiler->RecordSafepoint(locs());
-  // Marks either the continuation point in unoptimized code or the
-  // deoptimization point in optimized code, after call.
-  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
-  if (compiler->is_optimizing()) {
-    compiler->AddDeoptIndexAtCall(deopt_id_after);
-  }
-  // Add deoptimization continuation point after the call and before the
-  // arguments are removed.
-  // In optimized code this descriptor is needed for exception handling.
-  compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after,
-                                 token_pos());
+  compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
+                                 RawPcDescriptors::kOther, locs());
   __ Drop(argument_count);
 }
 
@@ -6191,7 +6174,6 @@
   const StubEntry stub_entry(stub);
   compiler->GenerateCall(token_pos(), stub_entry, RawPcDescriptors::kOther,
                          locs());
-  compiler->AddStubCallTarget(stub);
   __ Drop(ArgumentCount());  // Discard arguments.
 }
 
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index b1570d7..322e888 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -489,6 +489,9 @@
     f->Print(", ");
     PushArgumentAt(i)->value()->PrintTo(f);
   }
+  if (entry_kind() == Code::EntryKind::kUnchecked) {
+    f->Print(" using unchecked entrypoint");
+  }
 }
 
 void InstanceCallInstr::PrintOperandsTo(BufferFormatter* f) const {
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index d214aef..b6fbb07 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -864,7 +864,7 @@
   if (link_lazily()) {
     stub_entry = StubCode::CallBootstrapNative_entry();
     ExternalLabel label(NativeEntry::LinkNativeCallEntry());
-    __ LoadNativeEntry(RBX, &label, kPatchable);
+    __ LoadNativeEntry(RBX, &label, ObjectPool::kPatchable);
     compiler->GeneratePatchableCall(token_pos(), *stub_entry,
                                     RawPcDescriptors::kOther, locs());
   } else {
@@ -876,7 +876,7 @@
       stub_entry = StubCode::CallNoScopeNative_entry();
     }
     const ExternalLabel label(reinterpret_cast<uword>(native_c_function()));
-    __ LoadNativeEntry(RBX, &label, kNotPatchable);
+    __ LoadNativeEntry(RBX, &label, ObjectPool::kNotPatchable);
     compiler->GenerateCall(token_pos(), *stub_entry, RawPcDescriptors::kOther,
                            locs());
   }
@@ -1037,7 +1037,6 @@
     compiler->SaveLiveRegisters(locs);
     compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
                            stub_entry, RawPcDescriptors::kOther, locs);
-    compiler->AddStubCallTarget(stub);
     __ MoveRegister(result_, RAX);
     compiler->RestoreLiveRegisters(locs);
     __ jmp(exit_label());
@@ -2267,9 +2266,6 @@
   }
 
   __ Bind(&slow_path);
-  const Code& stub = Code::ZoneHandle(compiler->zone(),
-                                      StubCode::AllocateArray_entry()->code());
-  compiler->AddStubCallTarget(stub);
   compiler->GenerateCallWithDeopt(token_pos(), deopt_id(),
                                   *StubCode::AllocateArray_entry(),
                                   RawPcDescriptors::kOther, locs());
@@ -2539,9 +2535,6 @@
     compiler->SaveLiveRegisters(locs);
 
     __ LoadImmediate(R10, Immediate(instruction()->num_context_variables()));
-    const Code& stub = Code::ZoneHandle(
-        compiler->zone(), StubCode::AllocateContext_entry()->code());
-    compiler->AddStubCallTarget(stub);
     compiler->GenerateCall(instruction()->token_pos(),
                            *StubCode::AllocateContext_entry(),
                            RawPcDescriptors::kOther, locs);
@@ -6238,26 +6231,16 @@
   // Function in RAX.
   ASSERT(locs()->in(0).reg() == RAX);
   __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
-  __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
+  __ movq(RCX,
+          FieldAddress(RAX, Code::function_entry_point_offset(entry_kind())));
 
   // RAX: Function.
   // R10: Arguments descriptor array.
   // RBX: Smi 0 (no IC data; the lazy-compile stub expects a GC-safe value).
   __ xorq(RBX, RBX);
   __ call(RCX);
-  compiler->RecordSafepoint(locs());
-  compiler->EmitCatchEntryState();
-  // Marks either the continuation point in unoptimized code or the
-  // deoptimization point in optimized code, after call.
-  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
-  if (compiler->is_optimizing()) {
-    compiler->AddDeoptIndexAtCall(deopt_id_after);
-  }
-  // Add deoptimization continuation point after the call and before the
-  // arguments are removed.
-  // In optimized code this descriptor is needed for exception handling.
-  compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt, deopt_id_after,
-                                 token_pos());
+  compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
+                                 RawPcDescriptors::kOther, locs());
   __ Drop(argument_count);
 }
 
@@ -6297,7 +6280,6 @@
   const StubEntry stub_entry(stub);
   compiler->GenerateCall(token_pos(), stub_entry, RawPcDescriptors::kOther,
                          locs());
-  compiler->AddStubCallTarget(stub);
   __ Drop(ArgumentCount());  // Discard arguments.
 }
 
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index 0752327..6988601 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -971,6 +971,9 @@
           } else if (PolymorphicInstanceCallInstr* instr =
                          call_data->call->AsPolymorphicInstanceCall()) {
             entry_kind = instr->instance_call()->entry_kind();
+          } else if (ClosureCallInstr* instr =
+                         call_data->call->AsClosureCall()) {
+            entry_kind = instr->entry_kind();
           }
           kernel::FlowGraphBuilder builder(
               parsed_function, *ic_data_array, /* not building var desc */ NULL,
@@ -996,12 +999,14 @@
             CalleeGraphValidator::Validate(callee_graph);
           }
         }
-#ifdef DART_PRECOMPILER
+#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
+    !defined(TARGET_ARCH_IA32)
         if (FLAG_precompiled_mode) {
           Precompiler::PopulateWithICData(parsed_function->function(),
                                           callee_graph);
         }
-#endif
+#endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&           \
+    // !defined(TARGET_ARCH_IA32)
 
         // The parameter stubs are a copy of the actual arguments providing
         // concrete information about the values, for example constant values,
@@ -1080,7 +1085,8 @@
           // TODO(fschneider): Improve suppression of speculative inlining.
           // Deopt-ids overlap between caller and callee.
           if (FLAG_precompiled_mode) {
-#ifdef DART_PRECOMPILER
+#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
+    !defined(TARGET_ARCH_IA32)
             AotCallSpecializer call_specializer(inliner_->precompiler_,
                                                 callee_graph,
                                                 inliner_->speculative_policy_);
@@ -1102,7 +1108,8 @@
             callee_graph->Canonicalize();
 #else
             UNREACHABLE();
-#endif  // DART_PRECOMPILER
+#endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&           \
+        // !defined(TARGET_ARCH_IA32)
           } else {
             JitCallSpecializer call_specializer(callee_graph,
                                                 inliner_->speculative_policy_);
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index 0e4eea8..e74aaff 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -2613,7 +2613,6 @@
 // Right now we are attempting to sink allocation only into
 // deoptimization exit. So candidate should only be used in StoreInstanceField
 // instructions that write into fields of the allocated object.
-// We do not support materialization of the object that has type arguments.
 static bool IsAllocationSinkingCandidate(Definition* alloc,
                                          SafeUseCheck check_type) {
   for (Value* use = alloc->input_use_list(); use != NULL;
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index b81e5c6..b33a4cb 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -374,7 +374,7 @@
 
 COMPILER_PASS(AllocationSinking_Sink, {
   // TODO(vegorov): Support allocation sinking with try-catch.
-  if (flow_graph->graph_entry()->SuccessorCount() == 1) {
+  if (flow_graph->graph_entry()->catch_entries().is_empty()) {
     state->sinking = new AllocationSinking(flow_graph);
     state->sinking->Optimize();
   }
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index d92b3df..aab0242 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -271,7 +271,7 @@
         // InstanceField constant occupies 2 entries.
         // The first entry is used for field offset.
         obj = Smi::New(field.Offset() / kWordSize);
-        pool.SetTypeAt(i, ObjectPool::kTaggedObject);
+        pool.SetTypeAt(i, ObjectPool::kTaggedObject, ObjectPool::kNotPatchable);
         pool.SetObjectAt(i, obj);
         ++i;
         ASSERT(i < obj_count);
@@ -449,7 +449,7 @@
                                                        signature_type);
         closure.SetSignatureType(signature_type);
 
-        pool.SetTypeAt(i, ObjectPool::kTaggedObject);
+        pool.SetTypeAt(i, ObjectPool::kTaggedObject, ObjectPool::kNotPatchable);
         pool.SetObjectAt(i, closure);
 
         // Continue reading the constant pool entries inside the opened
@@ -464,7 +464,7 @@
       case ConstantPoolTag::kEndClosureFunctionScope: {
         // Entry is not used and set to null.
         obj = Object::null();
-        pool.SetTypeAt(i, ObjectPool::kTaggedObject);
+        pool.SetTypeAt(i, ObjectPool::kTaggedObject, ObjectPool::kNotPatchable);
         pool.SetObjectAt(i, obj);
         return i;  // The caller will close the scope.
       } break;
@@ -500,7 +500,7 @@
       default:
         UNREACHABLE();
     }
-    pool.SetTypeAt(i, ObjectPool::kTaggedObject);
+    pool.SetTypeAt(i, ObjectPool::kTaggedObject, ObjectPool::kNotPatchable);
     pool.SetObjectAt(i, obj);
   }
   // Return the index of the last read pool entry.
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index b7124b2..0cac1db 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1624,7 +1624,8 @@
   call_hook += LoadLocal(entry_point_num);
   call_hook += PushArgument();
   call_hook += Constant(Function::ZoneHandle(Z, closure.function()));
-  call_hook += B->ClosureCall(/*type_args_len=*/0, /*argument_count=*/3,
+  call_hook += B->ClosureCall(TokenPosition::kNoSource,
+                              /*type_args_len=*/0, /*argument_count=*/3,
                               /*argument_names=*/Array::Handle());
   call_hook += Drop();  // result of closure call
   call_hook += Drop();  // entrypoint number
@@ -2388,10 +2389,13 @@
   return flow_graph_builder_->LoadStaticField();
 }
 
-Fragment StreamingFlowGraphBuilder::CheckNull(TokenPosition position,
-                                              LocalVariable* receiver,
-                                              const String& function_name) {
-  return flow_graph_builder_->CheckNull(position, receiver, function_name);
+Fragment StreamingFlowGraphBuilder::CheckNull(
+    TokenPosition position,
+    LocalVariable* receiver,
+    const String& function_name,
+    bool clear_the_temp /* = true */) {
+  return flow_graph_builder_->CheckNull(position, receiver, function_name,
+                                        clear_the_temp);
 }
 
 Fragment StreamingFlowGraphBuilder::StaticCall(TokenPosition position,
@@ -2840,8 +2844,8 @@
   }
   for (intptr_t i = 0; i < list_length; ++i) {
     String& name =
-        H.DartSymbolObfuscate(ReadStringReference());    // read ith name index.
-    instructions += BuildExpression();                   // read ith expression.
+        H.DartSymbolObfuscate(ReadStringReference());  // read ith name index.
+    instructions += BuildExpression();                 // read ith expression.
     if (!skip_push_arguments) instructions += PushArgument();
     if (do_drop) instructions += Drop();
     if (argument_names != NULL) {
@@ -3452,6 +3456,11 @@
   const InferredTypeMetadata result_type =
       inferred_type_metadata_helper_.GetInferredType(offset);
 
+#ifndef TARGET_ARCH_DBC
+  const CallSiteAttributesMetadata call_site_attributes =
+      call_site_attributes_metadata_helper_.GetCallSiteAttributes(offset);
+#endif
+
   const Tag receiver_tag = PeekTag();  // peek tag for receiver.
   if (IsNumberLiteral(receiver_tag) &&
       (!optimizing() || constant_evaluator_.IsCached(offset))) {
@@ -3487,6 +3496,16 @@
     SetOffset(before_branch_offset);
   }
 
+  bool is_unchecked_closure_call = false;
+#ifndef TARGET_ARCH_DBC
+  if (call_site_attributes.receiver_type != nullptr &&
+      call_site_attributes.receiver_type->IsFunctionType()) {
+    AlternativeReadingScope alt(&reader_);
+    SkipExpression();  // skip receiver
+    is_unchecked_closure_call = ReadNameAsMethodName().Equals(Symbols::Call());
+  }
+#endif
+
   Fragment instructions;
 
   intptr_t type_args_len = 0;
@@ -3501,7 +3520,7 @@
       const TypeArguments& type_arguments =
           T.BuildTypeArguments(list_length);  // read types.
       instructions += TranslateInstantiatedTypeArguments(type_arguments);
-      if (direct_call.check_receiver_for_null_) {
+      if (direct_call.check_receiver_for_null_ || is_unchecked_closure_call) {
         // Don't yet push type arguments if we need to check receiver for null.
         // In this case receiver will be duplicated so instead of pushing
         // type arguments here we need to push it between receiver_temp
@@ -3538,7 +3557,7 @@
   }
 
   LocalVariable* receiver_temp = NULL;
-  if (direct_call.check_receiver_for_null_) {
+  if (direct_call.check_receiver_for_null_ || is_unchecked_closure_call) {
     // Duplicate receiver for CheckNull before it is consumed by PushArgument.
     receiver_temp = MakeTemporary();
     if (type_arguments_temp != NULL) {
@@ -3583,11 +3602,26 @@
             Field::GetterSymbol(name) == interface_target->name()));
   }
 
-  if (direct_call.check_receiver_for_null_) {
-    instructions += CheckNull(position, receiver_temp, name);
+  // TODO(sjindel): Avoid the check for null on unchecked closure calls if TFA
+  // allows.
+  if (direct_call.check_receiver_for_null_ || is_unchecked_closure_call) {
+    // Receiver temp is needed to load the function to call from the closure.
+    instructions += CheckNull(position, receiver_temp, name,
+                              /*clear_temp=*/!is_unchecked_closure_call);
   }
 
-  if (!direct_call.target_.IsNull()) {
+  if (is_unchecked_closure_call) {
+    // Lookup the function in the closure.
+    instructions += LoadLocal(receiver_temp);
+    instructions += LoadField(Closure::function_offset());
+    if (parsed_function()->function().is_debuggable()) {
+      ASSERT(!parsed_function()->function().is_native());
+      instructions += DebugStepCheck(position);
+    }
+    instructions +=
+        B->ClosureCall(position, type_args_len, argument_count, argument_names,
+                       /*use_unchecked_entry=*/true);
+  } else if (!direct_call.target_.IsNull()) {
     ASSERT(FLAG_precompiled_mode);
     instructions += StaticCall(position, direct_call.target_, argument_count,
                                argument_names, ICData::kNoRebind, &result_type,
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index ebdf3a0..c4aecce 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -209,7 +209,8 @@
   Fragment LoadStaticField();
   Fragment CheckNull(TokenPosition position,
                      LocalVariable* receiver,
-                     const String& function_name);
+                     const String& function_name,
+                     bool clear_the_temp = true);
   Fragment StaticCall(TokenPosition position,
                       const Function& target,
                       intptr_t argument_count,
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 769f2a9..53d17b4 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -356,10 +356,10 @@
     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);
+  InstanceCallInstr* call = new (Z)
+      InstanceCallInstr(position, name, kind, arguments, type_args_len,
+                        argument_names, checked_argument_count, ic_data_array_,
+                        GetNextDeoptId(), interface_target);
   if ((result_type != NULL) && !result_type->IsTrivial()) {
     call->SetResultType(Z, result_type->ToCompileType(Z));
   }
@@ -367,15 +367,19 @@
   return Fragment(call);
 }
 
-Fragment FlowGraphBuilder::ClosureCall(intptr_t type_args_len,
+Fragment FlowGraphBuilder::ClosureCall(TokenPosition position,
+                                       intptr_t type_args_len,
                                        intptr_t argument_count,
-                                       const Array& argument_names) {
+                                       const Array& argument_names,
+                                       bool is_statically_checked) {
   Value* function = Pop();
   const intptr_t total_count = argument_count + (type_args_len > 0 ? 1 : 0);
   ArgumentArray arguments = GetArguments(total_count);
   ClosureCallInstr* call = new (Z)
       ClosureCallInstr(function, arguments, type_args_len, argument_names,
-                       TokenPosition::kNoSource, GetNextDeoptId());
+                       position, GetNextDeoptId(),
+                       is_statically_checked ? Code::EntryKind::kUnchecked
+                                             : Code::EntryKind::kNormal);
   Push(call);
   return Fragment(call);
 }
@@ -486,7 +490,8 @@
 
 Fragment FlowGraphBuilder::CheckNull(TokenPosition position,
                                      LocalVariable* receiver,
-                                     const String& function_name) {
+                                     const String& function_name,
+                                     bool clear_the_temp /* = true */) {
   Fragment instructions = LoadLocal(receiver);
 
   CheckNullInstr* check_null =
@@ -494,11 +499,13 @@
 
   instructions <<= check_null;
 
-  // Null out receiver to make sure it is not saved into the frame before
-  // doing the call.
-  instructions += NullConstant();
-  instructions += StoreLocal(TokenPosition::kNoSource, receiver);
-  instructions += Drop();
+  if (clear_the_temp) {
+    // Null out receiver to make sure it is not saved into the frame before
+    // doing the call.
+    instructions += NullConstant();
+    instructions += StoreLocal(TokenPosition::kNoSource, receiver);
+    instructions += Drop();
+  }
 
   return instructions;
 }
@@ -1352,8 +1359,8 @@
     body += LoadLocal(closure);
     body += LoadField(Closure::function_offset());
 
-    body += ClosureCall(descriptor.TypeArgsLen(), descriptor.Count(),
-                        argument_names);
+    body += ClosureCall(TokenPosition::kNoSource, descriptor.TypeArgsLen(),
+                        descriptor.Count(), argument_names);
   } else {
     const intptr_t kNumArgsChecked = 1;
     body += InstanceCall(TokenPosition::kMinSource, Symbols::Call(),
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index ee8efe8..49332d5 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -101,9 +101,11 @@
                         intptr_t checked_argument_count,
                         const Function& interface_target,
                         const InferredTypeMetadata* result_type = NULL);
-  Fragment ClosureCall(intptr_t type_args_len,
+  Fragment ClosureCall(TokenPosition position,
+                       intptr_t type_args_len,
                        intptr_t argument_count,
-                       const Array& argument_names);
+                       const Array& argument_names,
+                       bool use_unchecked_entry = false);
   Fragment RethrowException(TokenPosition position, int catch_try_index);
   Fragment LoadClassId();
   Fragment LoadField(intptr_t offset, intptr_t class_id = kDynamicCid);
@@ -114,7 +116,8 @@
   Fragment Return(TokenPosition position, bool omit_result_type_check = false);
   Fragment CheckNull(TokenPosition position,
                      LocalVariable* receiver,
-                     const String& function_name);
+                     const String& function_name,
+                     bool clear_the_temp = true);
   void SetResultTypeForStaticCall(StaticCallInstr* call,
                                   const Function& target,
                                   intptr_t argument_count,
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index e14578b..aad6e73 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -896,7 +896,8 @@
 
       ASSERT(pass_state.inline_id_to_function.length() ==
              pass_state.caller_inline_id.length());
-      Assembler assembler(use_far_branches);
+      ObjectPoolWrapper object_pool_wrapper;
+      Assembler assembler(&object_pool_wrapper, use_far_branches);
       FlowGraphCompiler graph_compiler(
           &assembler, flow_graph, *parsed_function(), optimized(),
           &speculative_policy, pass_state.inline_id_to_function,
@@ -1220,7 +1221,8 @@
 }
 
 RawObject* Compiler::CompileFunction(Thread* thread, const Function& function) {
-#ifdef DART_PRECOMPILER
+#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
+    !defined(TARGET_ARCH_IA32)
   if (FLAG_precompiled_mode) {
     return Precompiler::CompileFunction(
         /* precompiler = */ NULL, thread, thread->zone(), function);
@@ -1416,8 +1418,13 @@
   for (int i = 0; i < functions.Length(); i++) {
     func ^= functions.At(i);
     ASSERT(!func.IsNull());
-    if (!func.HasCode() && !func.is_abstract() &&
-        !func.IsRedirectingFactory()) {
+    if (!func.HasCode() &&
+#if defined(DART_USE_INTERPRETER)
+        // TODO(regis): Revisit.
+        // Do not compile function if its bytecode is already loaded.
+        !func.HasBytecode() &&
+#endif
+        !func.is_abstract() && !func.IsRedirectingFactory()) {
       if ((cls.is_mixin_app_alias() || cls.IsMixinApplication()) &&
           func.HasOptionalParameters()) {
         // Skipping optional parameters in mixin application.
@@ -1427,7 +1434,13 @@
       if (result.IsError()) {
         return Error::Cast(result).raw();
       }
+#if defined(DART_USE_INTERPRETER)
+      // TODO(regis): Revisit.
+      // The compiler may load bytecode and return Code::null().
+      ASSERT(!result.IsNull() || func.HasBytecode());
+#else
       ASSERT(!result.IsNull());
+#endif
     }
   }
   return Error::null();
@@ -1467,7 +1480,8 @@
 }
 
 RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
-#ifdef DART_PRECOMPILER
+#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
+    !defined(TARGET_ARCH_IA32)
   if (FLAG_precompiled_mode) {
     return Precompiler::EvaluateStaticInitializer(field);
   }
@@ -1535,7 +1549,8 @@
 }
 
 RawObject* Compiler::ExecuteOnce(SequenceNode* fragment) {
-#ifdef DART_PRECOMPILER
+#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&                  \
+    !defined(TARGET_ARCH_IA32)
   if (FLAG_precompiled_mode) {
     return Precompiler::ExecuteOnce(fragment);
   }
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index 9beae96..a7b8922 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -118,6 +118,12 @@
 //    Jump to the given target if assertions are not enabled.
 //    Target is specified as offset from the PC of the jump instruction.
 //
+//  - JumpIfNotZeroTypeArgs target
+//
+//    Jump to the given target if number of passed function type
+//    arguments is not zero.
+//    Target is specified as offset from the PC of the jump instruction.
+//
 //  - Return R; ReturnTOS
 //
 //    Return to the caller using either a value from the given register or a
@@ -563,6 +569,13 @@
 //    Function prologue for the function
 //        rD - number of local slots to reserve;
 //
+//  - EntryFixed A, D
+//
+//    Function prologue for functions without optional arguments.
+//    Checks number of arguments.
+//        A - expected number of positional arguments;
+//        D - number of local slots to reserve;
+//
 //  - EntryOptional A, B, C
 //
 //    Function prologue for the function with optional or named arguments:
@@ -808,6 +821,7 @@
   V(Drop,                                  A, num, ___, ___)                   \
   V(Jump,                                  T, tgt, ___, ___)                   \
   V(JumpIfNoAsserts,                       T, tgt, ___, ___)                   \
+  V(JumpIfNotZeroTypeArgs,                 T, tgt, ___, ___)                   \
   V(Return,                                A, reg, ___, ___)                   \
   V(ReturnTOS,                             0, ___, ___, ___)                   \
   V(Move,                                A_X, reg, xeg, ___)                   \
@@ -969,6 +983,7 @@
   V(BooleanNegate,                       A_D, reg, reg, ___)                   \
   V(Throw,                                 A, num, ___, ___)                   \
   V(Entry,                                 D, num, ___, ___)                   \
+  V(EntryFixed,                          A_D, num, num, ___)                   \
   V(EntryOptional,                     A_B_C, num, num, num)                   \
   V(EntryOptimized,                      A_D, num, num, ___)                   \
   V(Frame,                                 D, num, ___, ___)                   \
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 1c2c099..7563e2a 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -1841,6 +1841,26 @@
   }
 
   {
+    BYTECODE(EntryFixed, A_D);
+    const uint16_t num_fixed_params = rA;
+    const uint16_t num_locals = rD;
+
+    const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_);
+    const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_);
+    if ((arg_count != num_fixed_params) || (pos_count != num_fixed_params)) {
+      goto ClosureNoSuchMethod;
+    }
+
+    // Initialize locals with null & set SP.
+    for (intptr_t i = 0; i < num_locals; i++) {
+      FP[i] = null_value;
+    }
+    SP = FP + num_locals - 1;
+
+    DISPATCH();
+  }
+
+  {
     BYTECODE(EntryOptional, A_B_C);
     const uint16_t num_fixed_params = rA;
     const uint16_t num_opt_pos_params = rB;
@@ -4437,6 +4457,15 @@
   }
 
   {
+    BYTECODE(JumpIfNotZeroTypeArgs, 0);
+    if (InterpreterHelpers::ArgDescTypeArgsLen(argdesc_) != 0) {
+      const int32_t target = static_cast<int32_t>(op) >> 8;
+      pc += (target - 1);
+    }
+    DISPATCH();
+  }
+
+  {
     BYTECODE(LoadClassId, A_D);
     const uint16_t object_reg = rD;
     RawObject* obj = static_cast<RawObject*>(FP[object_reg]);
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h
index 2005f9a..d832205 100644
--- a/runtime/vm/interpreter.h
+++ b/runtime/vm/interpreter.h
@@ -53,9 +53,8 @@
   uword stack_limit() const { return stack_limit_; }
 
   // Returns true if the interpreter's stack contains the given frame.
-  // TODO(regis): Once the interpreter shares the native stack, we may rely on
-  // a new thread vm_tag to identify an interpreter frame and we will not need
-  // this HasFrame() method.
+  // TODO(regis): We should rely on a new thread vm_tag to identify an
+  // interpreter frame and not need this HasFrame() method.
   bool HasFrame(uword frame) const {
     return frame >= stack_base() && frame <= get_fp();
   }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 38fdde9..d6fd7cb 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -5959,7 +5959,7 @@
   StorePointer(&raw_ptr()->code_, value.raw());
   StoreNonPointer(&raw_ptr()->entry_point_, value.EntryPoint());
   StoreNonPointer(&raw_ptr()->unchecked_entry_point_,
-                  value.unchecked_entry_point());
+                  value.UncheckedEntryPoint());
 }
 
 void Function::AttachCode(const Code& value) const {
@@ -13487,7 +13487,7 @@
     result ^= raw;
     result.SetLength(len);
     for (intptr_t i = 0; i < len; i++) {
-      result.SetTypeAt(i, ObjectPool::kImmediate);
+      result.SetTypeAt(i, ObjectPool::kImmediate, ObjectPool::kPatchable);
     }
   }
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index af38d51..9628163 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -4356,6 +4356,15 @@
     kNativeFunctionWrapper,
   };
 
+  enum Patchability {
+    kPatchable,
+    kNotPatchable,
+  };
+
+  class TypeBits : public BitField<uint8_t, EntryType, 0, 7> {};
+  class PatchableBit
+      : public BitField<uint8_t, Patchability, TypeBits::kNextBit, 1> {};
+
   struct Entry {
     Entry() : raw_value_(), type_() {}
     explicit Entry(const Object* obj) : obj_(obj), type_(kTaggedObject) {}
@@ -4382,11 +4391,17 @@
   }
 
   EntryType TypeAt(intptr_t index) const {
-    return static_cast<EntryType>(raw_ptr()->entry_types()[index]);
+    return TypeBits::decode(raw_ptr()->entry_bits()[index]);
   }
-  void SetTypeAt(intptr_t index, EntryType type) const {
-    StoreNonPointer(&raw_ptr()->entry_types()[index],
-                    static_cast<uint8_t>(type));
+
+  Patchability PatchableAt(intptr_t index) const {
+    return PatchableBit::decode(raw_ptr()->entry_bits()[index]);
+  }
+
+  void SetTypeAt(intptr_t index, EntryType type, Patchability patchable) const {
+    const uint8_t bits =
+        PatchableBit::encode(patchable) | TypeBits::encode(type);
+    StoreNonPointer(&raw_ptr()->entry_bits()[index], bits);
   }
 
   RawObject* ObjectAt(intptr_t index) const {
@@ -4990,6 +5005,18 @@
     }
   }
 
+  static intptr_t function_entry_point_offset(EntryKind kind) {
+    switch (kind) {
+      case Code::EntryKind::kNormal:
+        return Function::entry_point_offset();
+      case Code::EntryKind::kUnchecked:
+        return Function::unchecked_entry_point_offset();
+      default:
+        ASSERT(false && "Invalid entry kind.");
+        UNREACHABLE();
+    }
+  }
+
   RawObjectPool* object_pool() const { return raw_ptr()->object_pool_; }
   static intptr_t object_pool_offset() {
     return OFFSET_OF(RawCode, object_pool_);
@@ -5009,9 +5036,9 @@
   uword PayloadStart() const {
     return Instructions::PayloadStart(instructions());
   }
-  uword EntryPoint() const {
-    const Instructions& instr = Instructions::Handle(instructions());
-    return instr.EntryPoint();
+  uword EntryPoint() const { return Instructions::EntryPoint(instructions()); }
+  uword UncheckedEntryPoint() const {
+    return Instructions::UncheckedEntryPoint(instructions());
   }
   uword MonomorphicEntryPoint() const {
     const Instructions& instr = Instructions::Handle(instructions());
@@ -5306,14 +5333,6 @@
 
   bool IsDisabled() const { return instructions() != active_instructions(); }
 
-  uword unchecked_entry_point() const {
-    return raw_ptr()->unchecked_entry_point_;
-  }
-
-  void set_unchecked_entry_point(uword value) const {
-    StoreNonPointer(&raw_ptr()->unchecked_entry_point_, value);
-  }
-
  private:
   void set_state_bits(intptr_t bits) const;
 
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 060c1c5..35bc8dd 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2618,7 +2618,8 @@
 // Test for Code and Instruction object creation.
 ISOLATE_UNIT_TEST_CASE(Code) {
   extern void GenerateIncrement(Assembler * assembler);
-  Assembler _assembler_;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler _assembler_(&object_pool_wrapper);
   GenerateIncrement(&_assembler_);
   const Function& function = Function::Handle(CreateFunction("Test_Code"));
   Code& code =
@@ -2639,7 +2640,8 @@
       MallocHooks::stack_trace_collection_enabled();
   MallocHooks::set_stack_trace_collection_enabled(false);
   extern void GenerateIncrement(Assembler * assembler);
-  Assembler _assembler_;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler _assembler_(&object_pool_wrapper);
   GenerateIncrement(&_assembler_);
   const Function& function = Function::Handle(CreateFunction("Test_Code"));
   Code& code =
@@ -2665,7 +2667,8 @@
   extern void GenerateEmbedStringInCode(Assembler * assembler, const char* str);
   const char* kHello = "Hello World!";
   word expected_length = static_cast<word>(strlen(kHello));
-  Assembler _assembler_;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler _assembler_(&object_pool_wrapper);
   GenerateEmbedStringInCode(&_assembler_, kHello);
   const Function& function =
       Function::Handle(CreateFunction("Test_EmbedStringInCode"));
@@ -2687,7 +2690,8 @@
 ISOLATE_UNIT_TEST_CASE(EmbedSmiInCode) {
   extern void GenerateEmbedSmiInCode(Assembler * assembler, intptr_t value);
   const intptr_t kSmiTestValue = 5;
-  Assembler _assembler_;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler _assembler_(&object_pool_wrapper);
   GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue);
   const Function& function =
       Function::Handle(CreateFunction("Test_EmbedSmiInCode"));
@@ -2704,7 +2708,8 @@
 ISOLATE_UNIT_TEST_CASE(EmbedSmiIn64BitCode) {
   extern void GenerateEmbedSmiInCode(Assembler * assembler, intptr_t value);
   const intptr_t kSmiTestValue = DART_INT64_C(5) << 32;
-  Assembler _assembler_;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler _assembler_(&object_pool_wrapper);
   GenerateEmbedSmiInCode(&_assembler_, kSmiTestValue);
   const Function& function =
       Function::Handle(CreateFunction("Test_EmbedSmiIn64BitCode"));
@@ -2734,7 +2739,8 @@
                                     TokenPosition::kNoSource, true);
 
   extern void GenerateIncrement(Assembler * assembler);
-  Assembler _assembler_;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler _assembler_(&object_pool_wrapper);
   GenerateIncrement(&_assembler_);
   Code& code = Code::Handle(Code::FinalizeCode(
       Function::Handle(CreateFunction("Test_Code")), nullptr, &_assembler_));
@@ -2774,7 +2780,8 @@
   descriptors ^= builder->FinalizePcDescriptors(0);
 
   extern void GenerateIncrement(Assembler * assembler);
-  Assembler _assembler_;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler _assembler_(&object_pool_wrapper);
   GenerateIncrement(&_assembler_);
   Code& code = Code::Handle(Code::FinalizeCode(
       Function::Handle(CreateFunction("Test_Code")), nullptr, &_assembler_));
@@ -2835,7 +2842,8 @@
   descriptors ^= builder->FinalizePcDescriptors(0);
 
   extern void GenerateIncrement(Assembler * assembler);
-  Assembler _assembler_;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler _assembler_(&object_pool_wrapper);
   GenerateIncrement(&_assembler_);
   Code& code = Code::Handle(Code::FinalizeCode(
       Function::Handle(CreateFunction("Test_Code")), nullptr, &_assembler_));
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 92833a5..71442f9 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -529,10 +529,10 @@
                                                 ObjectPointerVisitor* visitor) {
   const intptr_t length = raw_obj->ptr()->length_;
   RawObjectPool::Entry* entries = raw_obj->ptr()->data();
-  uint8_t* entry_types = raw_obj->ptr()->entry_types();
+  uint8_t* entry_bits = raw_obj->ptr()->entry_bits();
   for (intptr_t i = 0; i < length; ++i) {
     ObjectPool::EntryType entry_type =
-        static_cast<ObjectPool::EntryType>(entry_types[i]);
+        ObjectPool::TypeBits::decode(entry_bits[i]);
     if (entry_type == ObjectPool::kTaggedObject) {
       visitor->VisitPointer(&entries[i].raw_obj_);
     }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index dc6bcc9..1738a30 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1368,12 +1368,10 @@
   Entry* data() { OPEN_ARRAY_START(Entry, Entry); }
   Entry const* data() const { OPEN_ARRAY_START(Entry, Entry); }
 
-  // The entry types are located after the last entry. They are interpreted
-  // as ObjectPool::EntryType.
-  uint8_t* entry_types() {
-    return reinterpret_cast<uint8_t*>(&data()[length_]);
-  }
-  uint8_t const* entry_types() const {
+  // The entry bits are located after the last entry. They are encoded versions
+  // of `ObjectPool::TypeBits() | ObjectPool::PatchabililtyBit()`.
+  uint8_t* entry_bits() { return reinterpret_cast<uint8_t*>(&data()[length_]); }
+  uint8_t const* entry_bits() const {
     return reinterpret_cast<uint8_t const*>(&data()[length_]);
   }
 
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index ee2f77c..8535bcd 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -578,9 +578,10 @@
 #if defined(DART_USE_INTERPRETER)
 void StackFrameIterator::FrameSetIterator::CheckIfInterpreted(
     uword exit_marker) {
-  // TODO(regis): Once the interpreter shares the native stack, we may rely on
-  // a new thread vm_tag to identify an interpreter frame.
-  Interpreter* interpreter = thread_->isolate()->interpreter();
+  // TODO(regis): We should rely on a new thread vm_tag to identify an
+  // interpreter frame and not need the HasFrame() method.
+  Isolate* isolate = thread_->isolate();
+  Interpreter* interpreter = isolate != NULL ? isolate->interpreter() : NULL;
   is_interpreted_ = (interpreter != NULL) && interpreter->HasFrame(exit_marker);
 }
 #endif
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 6ee2181..82e4767 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -60,7 +60,8 @@
 
 RawCode* StubCode::Generate(const char* name,
                             void (*GenerateStub)(Assembler* assembler)) {
-  Assembler assembler;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler assembler(&object_pool_wrapper);
   GenerateStub(&assembler);
   const Code& code = Code::Handle(
       Code::FinalizeCode(name, nullptr, &assembler, false /* optimized */));
@@ -139,7 +140,8 @@
   Code& stub = Code::Handle(zone, cls.allocation_stub());
 #if !defined(DART_PRECOMPILED_RUNTIME)
   if (stub.IsNull()) {
-    Assembler assembler;
+    ObjectPoolWrapper object_pool_wrapper;
+    Assembler assembler(&object_pool_wrapper);
     const char* name = cls.ToCString();
     StubCode::GenerateAllocationStubForClass(&assembler, cls);
 
diff --git a/runtime/vm/stub_code_arm64_test.cc b/runtime/vm/stub_code_arm64_test.cc
index 2f2495e..091cb42 100644
--- a/runtime/vm/stub_code_arm64_test.cc
+++ b/runtime/vm/stub_code_arm64_test.cc
@@ -55,7 +55,8 @@
                                               const Code& code);
   const int length = 10;
   const char* kName = "Test_CallRuntimeStubCode";
-  Assembler assembler;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler assembler(&object_pool_wrapper);
   GenerateCallToCallRuntimeStub(&assembler, length);
   const Code& code = Code::Handle(Code::FinalizeCode(
       *CreateFunction("Test_CallRuntimeStubCode"), nullptr, &assembler));
@@ -94,7 +95,8 @@
   intptr_t rhs_index_value = 2;
   intptr_t length_value = 2;
   const char* kName = "Test_CallLeafRuntimeStubCode";
-  Assembler assembler;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler assembler(&object_pool_wrapper);
   GenerateCallToCallLeafRuntimeStub(&assembler, str_value, lhs_index_value,
                                     rhs_index_value, length_value);
   const Code& code = Code::Handle(Code::FinalizeCode(
diff --git a/runtime/vm/stub_code_arm_test.cc b/runtime/vm/stub_code_arm_test.cc
index d7f44bc..e717208 100644
--- a/runtime/vm/stub_code_arm_test.cc
+++ b/runtime/vm/stub_code_arm_test.cc
@@ -55,7 +55,8 @@
                                               const Code& code);
   const int length = 10;
   const char* kName = "Test_CallRuntimeStubCode";
-  Assembler assembler;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler assembler(&object_pool_wrapper);
   GenerateCallToCallRuntimeStub(&assembler, length);
   const Code& code = Code::Handle(Code::FinalizeCode(
       *CreateFunction("Test_CallRuntimeStubCode"), nullptr, &assembler));
@@ -94,7 +95,8 @@
   intptr_t rhs_index_value = 2;
   intptr_t length_value = 2;
   const char* kName = "Test_CallLeafRuntimeStubCode";
-  Assembler assembler;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler assembler(&object_pool_wrapper);
   GenerateCallToCallLeafRuntimeStub(&assembler, str_value, lhs_index_value,
                                     rhs_index_value, length_value);
   const Code& code = Code::Handle(Code::FinalizeCode(
diff --git a/runtime/vm/stub_code_ia32_test.cc b/runtime/vm/stub_code_ia32_test.cc
index 4e1df07..e00932a 100644
--- a/runtime/vm/stub_code_ia32_test.cc
+++ b/runtime/vm/stub_code_ia32_test.cc
@@ -55,7 +55,7 @@
                                               const Code& code);
   const int length = 10;
   const char* kName = "Test_CallRuntimeStubCode";
-  Assembler assembler;
+  Assembler assembler(nullptr);
   GenerateCallToCallRuntimeStub(&assembler, length);
   const Code& code = Code::Handle(Code::FinalizeCode(
       *CreateFunction("Test_CallRuntimeStubCode"), nullptr, &assembler));
@@ -98,7 +98,7 @@
   intptr_t rhs_index_value = 2;
   intptr_t length_value = 2;
   const char* kName = "Test_CallLeafRuntimeStubCode";
-  Assembler assembler;
+  Assembler assembler(nullptr);
   GenerateCallToCallLeafRuntimeStub(&assembler, str_value, lhs_index_value,
                                     rhs_index_value, length_value);
   const Code& code = Code::Handle(Code::FinalizeCode(
diff --git a/runtime/vm/stub_code_x64_test.cc b/runtime/vm/stub_code_x64_test.cc
index cc108ae..b460282 100644
--- a/runtime/vm/stub_code_x64_test.cc
+++ b/runtime/vm/stub_code_x64_test.cc
@@ -55,7 +55,8 @@
                                               const Code& code);
   const int length = 10;
   const char* kName = "Test_CallRuntimeStubCode";
-  Assembler assembler;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler assembler(&object_pool_wrapper);
   GenerateCallToCallRuntimeStub(&assembler, length);
   const Code& code = Code::Handle(Code::FinalizeCode(
       *CreateFunction("Test_CallRuntimeStubCode"), nullptr, &assembler));
@@ -94,7 +95,8 @@
   intptr_t rhs_index_value = 2;
   intptr_t length_value = 2;
   const char* kName = "Test_CallLeafRuntimeStubCode";
-  Assembler assembler;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler assembler(&object_pool_wrapper);
   GenerateCallToCallLeafRuntimeStub(&assembler, str_value, lhs_index_value,
                                     rhs_index_value, length_value);
   const Code& code = Code::Handle(Code::FinalizeCode(
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index 92e04a1..07200fb 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -496,11 +496,11 @@
 // to get their verification done and exit. Use a specific UserTag
 // to enable the helpers to verify that the main thread is
 // successfully interrupted in the pure Dart loop.
-#if defined(USING_SIMULATOR)
+#if defined(USING_SIMULATOR) || defined(DART_USE_INTERPRETER)
   const intptr_t kLoopCount = 12345678;
 #else
   const intptr_t kLoopCount = 1234567890;
-#endif  // USING_SIMULATOR
+#endif  // defined(USING_SIMULATOR) || defined(DART_USE_INTERPRETER)
   char buffer[1024];
   Utils::SNPrint(buffer, sizeof(buffer),
                  "import 'dart:developer';\n"
diff --git a/runtime/vm/type_testing_stubs.cc b/runtime/vm/type_testing_stubs.cc
index da216ee..2e635c1 100644
--- a/runtime/vm/type_testing_stubs.cc
+++ b/runtime/vm/type_testing_stubs.cc
@@ -345,7 +345,8 @@
   ASSERT(!type_class.IsNull());
 
   // To use the already-defined __ Macro !
-  Assembler assembler;
+  ObjectPoolWrapper object_pool_wrapper;
+  Assembler assembler(&object_pool_wrapper);
   BuildOptimizedTypeTestStub(&assembler, hi, type, type_class);
 
   const char* name = namer_.StubNameForType(type);
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 1d125a0..7ff72fd 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -28,17 +28,13 @@
 using dart::bin::DartUtils;
 
 extern "C" {
-extern const uint8_t kPlatformDill[];
 extern const uint8_t kPlatformStrongDill[];
-extern intptr_t kPlatformDillSize;
 extern intptr_t kPlatformStrongDillSize;
 }
 
 namespace dart {
 
-const uint8_t* platform_dill = kPlatformDill;
 const uint8_t* platform_strong_dill = kPlatformStrongDill;
-const intptr_t platform_dill_size = kPlatformDillSize;
 const intptr_t platform_strong_dill_size = kPlatformStrongDillSize;
 
 DEFINE_FLAG(bool,
@@ -109,8 +105,7 @@
 Dart_Isolate TestCase::CreateTestIsolate(const char* name, void* data) {
   if (FLAG_use_dart_frontend) {
     return CreateIsolate(
-        FLAG_strong ? platform_strong_dill : platform_dill,
-        FLAG_strong ? platform_strong_dill_size : platform_dill_size,
+        platform_strong_dill, platform_strong_dill_size,
         NULL, /* There is no instr buffer in case of dill buffers. */
         name, data);
   } else {
@@ -261,8 +256,7 @@
                                          bool allow_compile_errors) {
   Zone* zone = Thread::Current()->zone();
   Dart_KernelCompilationResult compilation_result = Dart_CompileSourcesToKernel(
-      url, FLAG_strong ? platform_strong_dill : platform_dill,
-      FLAG_strong ? platform_strong_dill_size : platform_dill_size,
+      url, platform_strong_dill, platform_strong_dill_size,
       sourcefiles_count, sourcefiles, incrementally, NULL);
   return ValidateCompilationResult(zone, compilation_result, kernel_pgm);
 }
@@ -311,10 +305,8 @@
                                          const char* multiroot_scheme) {
   Zone* zone = Thread::Current()->zone();
   Dart_KernelCompilationResult compilation_result = Dart_CompileSourcesToKernel(
-      url, FLAG_strong ? platform_strong_dill : platform_dill,
-      FLAG_strong ? platform_strong_dill_size : platform_dill_size,
-      sourcefiles_count, sourcefiles, incrementally, NULL, multiroot_filepaths,
-      multiroot_scheme);
+      url, platform_strong_dill, platform_strong_dill_size, sourcefiles_count,
+      sourcefiles, incrementally, NULL, multiroot_filepaths, multiroot_scheme);
   return ValidateCompilationResult(zone, compilation_result, kernel_buffer,
                                    kernel_buffer_size, allow_compile_errors);
 }
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 928489f..1115f6d 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -90,7 +90,8 @@
       bool use_far_branches = false;                                           \
       LongJumpScope jump;                                                      \
       if (setjmp(*jump.Set()) == 0) {                                          \
-        Assembler assembler(use_far_branches);                                 \
+        ObjectPoolWrapper object_pool_wrapper;                                 \
+        Assembler assembler(&object_pool_wrapper, use_far_branches);           \
         AssemblerTest test("" #name, &assembler);                              \
         AssemblerTestGenerate##name(test.assembler());                         \
         test.Assemble();                                                       \
@@ -102,7 +103,8 @@
     const Error& error = Error::Handle(Thread::Current()->sticky_error());     \
     if (error.raw() == Object::branch_offset_error().raw()) {                  \
       bool use_far_branches = true;                                            \
-      Assembler assembler(use_far_branches);                                   \
+      ObjectPoolWrapper object_pool_wrapper;                                   \
+      Assembler assembler(&object_pool_wrapper, use_far_branches);             \
       AssemblerTest test("" #name, &assembler);                                \
       AssemblerTestGenerate##name(test.assembler());                           \
       test.Assemble();                                                         \
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index 2fa3f1df8..b5354bb 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -98,6 +98,7 @@
     show
         CastStream,
         CastStreamTransformer,
+        EmptyIterator,
         printToZone,
         printToConsole,
         IterableElementError;
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index 33a7ac4..f8ef8ed 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -159,19 +159,21 @@
   }
 
   /**
-   * Creates a single-subscription stream that gets its data from [data].
+   * Creates a single-subscription stream that gets its data from [elements].
    *
    * The iterable is iterated when the stream receives a listener, and stops
-   * iterating if the listener cancels the subscription.
+   * iterating if the listener cancels the subscription, or if the
+   * [Iterator.moveNext] method returns `false` or throws.
+   * Iteration is suspended whild the stream subscription is paused.
    *
-   * If iterating [data] throws an error, the stream ends immediately with
-   * that error. No done event will be sent (iteration is not complete), but no
-   * further data events will be generated either, since iteration cannot
-   * continue.
+   * If calling [Iterator.moveNext] on `elements.iterator` throws,
+   * the stream emits that error and then it closes.
+   * If reading [Iterator.current] on `elements.iterator` throws,
+   * the stream emits that error, but keeps iterating.
    */
-  factory Stream.fromIterable(Iterable<T> data) {
+  factory Stream.fromIterable(Iterable<T> elements) {
     return new _GeneratedStreamImpl<T>(
-        () => new _IterablePendingEvents<T>(data));
+        () => new _IterablePendingEvents<T>(elements));
   }
 
   /**
@@ -967,11 +969,18 @@
   /**
    * Collects the data of this stream in a [Set].
    *
+   * Creates a `Set<T>` and adds all elements of the stream to the set.
+   * in the order they arrive.
+   * When the stream ends, the returned future is completed with that set.
+   *
    * The returned set is the same type as returned by `new Set<T>()`.
    * If another type of set is needed, either use [forEach] to add each
    * element to the set, or use
    * `toList().then((list) => new SomeOtherSet.from(list))`
    * to create the set.
+   *
+   * If the stream contains an error, the returned future is completed
+   * with that error, and processing stops.
    */
   Future<Set<T>> toSet() {
     Set<T> result = new Set<T>();
@@ -1626,6 +1635,13 @@
    *
    * If the subscription is paused more than once, an equal number
    * of resumes must be performed to resume the stream.
+   * Calls to [resume] and the completion of a [resumeSignal] are
+   * interchangeable - the [pause] which was passed a [resumeSignal] may be
+   * ended by a call to [resume], and completing the [resumeSignal] may end a
+   * different [pause].
+   *
+   * It is safe to [resume] or complete a [resumeSignal] even when the
+   * subscription is not paused, and the resume will have no effect.
    *
    * Currently DOM streams silently drop events when the stream is paused. This
    * is a bug and will be fixed.
@@ -1639,6 +1655,9 @@
    * When all previously calls to [pause] have been matched by a calls to
    * [resume], possibly through a `resumeSignal` passed to [pause],
    * the stream subscription may emit events again.
+   *
+   * It is safe to [resume] even when the subscription is not paused, and the
+   * resume will have no effect.
    */
   void resume();
 
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index 310ec37..9750478 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -526,22 +526,29 @@
     }
     // Send one event per call to moveNext.
     // If moveNext returns true, send the current element as data.
+    // If current throws, send that error, but keep iterating.
     // If moveNext returns false, send a done event and clear the _iterator.
-    // If moveNext throws an error, send an error and clear the _iterator.
-    // After an error, no further events will be sent.
-    bool isDone;
+    // If moveNext throws an error, send an error and prepare to send a done
+    // event afterwards.
+    bool hasMore;
     try {
-      isDone = !_iterator.moveNext();
+      hasMore = _iterator.moveNext();
+      if (hasMore) {
+        dispatch._sendData(_iterator.current);
+      } else {
+        _iterator = null;
+        dispatch._sendDone();
+      }
     } catch (e, s) {
-      _iterator = null;
-      dispatch._sendError(e, s);
-      return;
-    }
-    if (!isDone) {
-      dispatch._sendData(_iterator.current);
-    } else {
-      _iterator = null;
-      dispatch._sendDone();
+      if (hasMore == null) {
+        // Threw in .moveNext().
+        // Ensure that we send a done afterwards.
+        _iterator = const EmptyIterator<Null>();
+        dispatch._sendError(e, s);
+      } else {
+        // Threw in .current.
+        dispatch._sendError(e, s);
+      }
     }
   }
 
diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart
index 3c7e1c2..b6c616a 100644
--- a/sdk/lib/io/process.dart
+++ b/sdk/lib/io/process.dart
@@ -288,6 +288,11 @@
    * which will be returned as the negative number `-1073741819`. To
    * get the original 32-bit value use `(0x100000000 + exitCode) &
    * 0xffffffff`.
+   *
+   * There is no guarantee that [stdout] and [stderr] have finished reporting
+   * the buffered output of the process when the returned future completes.
+   * To be sure that all output is captured,
+   * wait for the done event on the streams.
    */
   Future<int> get exitCode;
 
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 0a66fd4..b3d404f 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -907,6 +907,7 @@
 Utils/tests/Expect/setEquals_A01_t02: CompileTimeError # Uses Dart 1 constants
 
 [ !$strong ]
+LibTest/async/Stream/Stream.fromIterable_A02_t01: RuntimeError # Assumes no close after error.
 LibTest/async/Stream/firstWhere_A01_t01: RuntimeError # co19 issue 137
 LibTest/async/Stream/firstWhere_A02_t01: RuntimeError # co19 issue 137
 LibTest/async/Stream/lastWhere_A01_t01: RuntimeError # co19 issue 137
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index 1dfba79..95caf2c 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -4,7 +4,6 @@
 
 [ $compiler == fasta ]
 Language/Classes/Constructors/Generative_Constructors/final_variables_t01: CompileTimeError # Expects a warning, but this is an error in Dart 2
-Language/Classes/definition_t24: MissingCompileTimeError
 Language/Functions/Formal_Parameters/Optional_Formals/default_value_t01: MissingCompileTimeError
 Language/Functions/Formal_Parameters/Optional_Formals/default_value_t02: MissingCompileTimeError
 Language/Types/Type_Void/syntax_t08: MissingCompileTimeError
@@ -74,8 +73,6 @@
 Language/Classes/Setters/static_setter_t05: CompileTimeError
 Language/Classes/Setters/static_setter_t06: CompileTimeError
 Language/Classes/Static_Methods/same_name_method_and_setter_t01: CompileTimeError
-Language/Classes/Superinterfaces/more_than_once_t01: MissingCompileTimeError
-Language/Classes/Superinterfaces/superclass_as_superinterface_t01: MissingCompileTimeError
 Language/Classes/same_name_instance_and_static_members_t02: MissingCompileTimeError
 Language/Classes/same_name_instance_and_static_members_t04: MissingCompileTimeError
 Language/Expressions/Constants/exception_t01: MissingCompileTimeError
@@ -104,8 +101,6 @@
 Language/Classes/Getters/same_name_method_t04: MissingCompileTimeError
 Language/Classes/Getters/same_name_method_t05: MissingCompileTimeError
 Language/Classes/Getters/same_name_method_t07: MissingCompileTimeError
-Language/Classes/Superinterfaces/more_than_once_t01: MissingCompileTimeError
-Language/Classes/Superinterfaces/superclass_as_superinterface_t01: MissingCompileTimeError
 Language/Classes/same_name_instance_and_static_members_t02: MissingCompileTimeError
 Language/Classes/same_name_instance_and_static_members_t04: MissingCompileTimeError
 Language/Expressions/Constants/bitwise_operators_t05: MissingCompileTimeError
@@ -226,7 +221,6 @@
 Language/Classes/Superinterfaces/no_member_t02: CompileTimeError
 Language/Classes/Superinterfaces/no_member_t05: CompileTimeError
 Language/Classes/Superinterfaces/wrong_type_t05: MissingCompileTimeError
-Language/Classes/definition_t24: MissingCompileTimeError
 Language/Classes/method_definition_t03: CompileTimeError
 Language/Classes/method_definition_t04: CompileTimeError
 Language/Classes/method_definition_t05: CompileTimeError
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 055c317..3e28235 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -57,12 +57,9 @@
 Language/Classes/Setters/name_t06: CompileTimeError
 Language/Classes/Setters/name_t07: CompileTimeError
 Language/Classes/Static_Methods/same_name_method_and_setter_t01: CompileTimeError
-Language/Classes/Superclasses/wrong_superclass_t08: MissingCompileTimeError
-Language/Classes/Superinterfaces/more_than_once_t01: MissingCompileTimeError
-Language/Classes/Superinterfaces/superclass_as_superinterface_t01: MissingCompileTimeError
-Language/Classes/Superinterfaces/wrong_type_t05: MissingCompileTimeError
-Language/Classes/definition_t24: MissingCompileTimeError
-Language/Classes/method_definition_t06: MissingCompileTimeError
+Language/Classes/Superclasses/wrong_superclass_t08: MissingCompileTimeError # Issue 30273
+Language/Classes/Superinterfaces/wrong_type_t05: MissingCompileTimeError # Issue 30273
+Language/Classes/method_definition_t06: MissingCompileTimeError # Legal
 Language/Enums/syntax_t08: CompileTimeError
 Language/Enums/syntax_t09: CompileTimeError
 Language/Expressions/Assignable_Expressions/syntax_t01: CompileTimeError
@@ -257,7 +254,6 @@
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_l1_t02: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/interface/interface_neg_assign_l2_t01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/interface/interface_neg_assign_l2_t02: MissingCompileTimeError
-LanguageFeatures/Instantiate-to-bound/interface/interface_neg_l1_t06: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/mixin/mixin_extends_neg_l1_t01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/mixin/mixin_neg_assign_l2_t01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/mixin/mixin_neg_l1_t02: MissingCompileTimeError
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 150a79c..2c3682a 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -33,7 +33,7 @@
 model/subtype_test: Pass, Slow
 no_such_method_enabled_test: Pass, Slow
 packages/*: Skip # Skip packages folder
-rti/rti_emission_test: RuntimeError, Slow # Issue 34095
+rti/rti_emission_test: Pass, Slow
 rti/rti_need0_test: Pass, Slow
 rti/rti_need1_test: Pass, Slow
 show_package_warnings_test: RuntimeError # missing errors from the FE
diff --git a/tests/compiler/dart2js/rti/emission/constructor_argument_static_strong.dart b/tests/compiler/dart2js/rti/emission/constructor_argument_static_strong.dart
index 37dfefe..0725a31 100644
--- a/tests/compiler/dart2js/rti/emission/constructor_argument_static_strong.dart
+++ b/tests/compiler/dart2js/rti/emission/constructor_argument_static_strong.dart
@@ -4,12 +4,14 @@
 
 import 'package:meta/dart2js.dart';
 
-/*class: A1:checks=[],instance*/
+/*strong.class: A1:checkedInstance,checks=[],instance*/
+/*omit.class: A1:checks=[],instance*/
 class A1 {}
 
 // Constructor calls are always statically invoked, so there is no checks at the
 // entry and the `Test1` constructor does not cause any checks.
-/*class: B1:checks=[],instance*/
+/*strong.class: B1:checks=[$isA1],instance*/
+/*omit.class: B1:checks=[],instance*/
 class B1 implements A1 {}
 
 /*class: Test1:checks=[],instance*/
diff --git a/tests/compiler/dart2js/rti/emission/self.dart b/tests/compiler/dart2js/rti/emission/self.dart
index a6aa4a6..2777989 100644
--- a/tests/compiler/dart2js/rti/emission/self.dart
+++ b/tests/compiler/dart2js/rti/emission/self.dart
@@ -4,7 +4,7 @@
 
 import 'package:meta/dart2js.dart';
 
-/*class: C:checkedInstance,checks=[],instance*/
+/*class: C:checkedInstance,checks=[],instance,typeLiteral*/
 class C {}
 
 @noInline
diff --git a/tests/compiler/dart2js/rti/emission/superclass.dart b/tests/compiler/dart2js/rti/emission/superclass.dart
index e0427de..7af0de0 100644
--- a/tests/compiler/dart2js/rti/emission/superclass.dart
+++ b/tests/compiler/dart2js/rti/emission/superclass.dart
@@ -4,7 +4,7 @@
 
 import 'package:meta/dart2js.dart';
 
-/*class: B:checkedInstance,checks=[],instance*/
+/*class: B:checkedInstance,checks=[],typeLiteral*/
 class B {}
 
 /*class: C:checks=[],instance*/
diff --git a/tests/compiler/dart2js/rti/rti_emission_test.dart b/tests/compiler/dart2js/rti/rti_emission_test.dart
index d7f6b65..9659eb6 100644
--- a/tests/compiler/dart2js/rti/rti_emission_test.dart
+++ b/tests/compiler/dart2js/rti/rti_emission_test.dart
@@ -38,6 +38,12 @@
         'map_literal_checked.dart',
         // TODO(johnniwinther): Optimize local function type signature need.
         'subtype_named_args.dart',
+
+        // TODO(johnniwinther): Fix crash.
+        'call_strong.dart',
+
+        // TODO(34095):
+        'list.dart',
       ],
     );
   });
diff --git a/tests/compiler/dart2js_extra/deferred/34219_bounds_lib1.dart b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib1.dart
new file mode 100644
index 0000000..81bf0ae
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib1.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.
+
+// Part of 34219_bounds_test.dart
+
+import '34219_bounds_lib2.dart';
+
+class SystemMessage extends GeneratedMessage {}
+
+var g;
+
+test1() {
+  new GeneratedMessage();
+  g = (<T extends SystemMessage>(T a, T b) => a == b);
+}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_bounds_lib2.dart b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib2.dart
new file mode 100644
index 0000000..7726460
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib2.dart
@@ -0,0 +1,7 @@
+// 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 34219_bounds_test.dart
+
+class GeneratedMessage {}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_bounds_lib3.dart b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib3.dart
new file mode 100644
index 0000000..a567162
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_bounds_lib3.dart
@@ -0,0 +1,14 @@
+// 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 34219_bounds_test.dart
+//
+// This library places GeneratedMessage into a different partition to
+// SystemMessage.
+
+import '34219_bounds_lib2.dart';
+
+test3() {
+  new GeneratedMessage();
+}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_bounds_test.dart b/tests/compiler/dart2js_extra/deferred/34219_bounds_test.dart
new file mode 100644
index 0000000..67b77d9
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_bounds_test.dart
@@ -0,0 +1,20 @@
+// 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.
+// dart2jsOptions=--omit-implicit-checks
+
+// Tests that generic function type bounds are walked as dependencies of a
+// closure. If the generic function bounds are not visited, SystemMessage is
+// placed in the main unit while it's superclass GeneratedMessage is placed in a
+// deferred part.
+
+import '34219_bounds_lib1.dart' deferred as lib1;
+import '34219_bounds_lib3.dart' deferred as lib3;
+
+main() async {
+  await lib1.loadLibrary();
+  lib1.test1();
+  await lib3.loadLibrary();
+  lib3.test3();
+  if (lib1.g is bool Function(Object, Object)) print('!');
+}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_signature_lib1.dart b/tests/compiler/dart2js_extra/deferred/34219_signature_lib1.dart
new file mode 100644
index 0000000..b3493bd
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_signature_lib1.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.
+
+// Part of 34219_signature_test.dart
+
+import '34219_signature_lib2.dart';
+
+class SystemMessage extends GeneratedMessage {}
+
+var g;
+
+test1() {
+  new GeneratedMessage();
+  g = (SystemMessage a, SystemMessage b) => a == b;
+}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_signature_lib2.dart b/tests/compiler/dart2js_extra/deferred/34219_signature_lib2.dart
new file mode 100644
index 0000000..e702fe6
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_signature_lib2.dart
@@ -0,0 +1,7 @@
+// 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 34219_signature_test.dart
+
+class GeneratedMessage {}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_signature_lib3.dart b/tests/compiler/dart2js_extra/deferred/34219_signature_lib3.dart
new file mode 100644
index 0000000..35915d5
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_signature_lib3.dart
@@ -0,0 +1,14 @@
+// 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 34219_signature_test.dart
+//
+// This library places GeneratedMessage into a different partition to
+// SystemMessage.
+
+import '34219_signature_lib2.dart';
+
+test3() {
+  new GeneratedMessage();
+}
diff --git a/tests/compiler/dart2js_extra/deferred/34219_signature_test.dart b/tests/compiler/dart2js_extra/deferred/34219_signature_test.dart
new file mode 100644
index 0000000..d6c2c05
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/34219_signature_test.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.
+// dart2jsOptions=--omit-implicit-checks
+
+// Tests that closure signatures are walked as dependencies of a closure. If the
+// signature of the closure is not visited, SystemMessage is placed in the main
+// unit while it's superclass GeneratedMessage is placed in a deferred part.
+
+import '34219_signature_lib1.dart' deferred as lib1;
+import '34219_signature_lib3.dart' deferred as lib3;
+
+main() async {
+  await lib1.loadLibrary();
+  lib1.test1();
+  await lib3.loadLibrary();
+  lib3.test3();
+  if (lib1.g is bool Function(Object, Object)) print('!');
+}
diff --git a/tests/language_2/bug34235_test.dart b/tests/language_2/bug34235_test.dart
new file mode 100644
index 0000000..69011ff
--- /dev/null
+++ b/tests/language_2/bug34235_test.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.
+
+class Base {
+  void foo() {}
+}
+
+class M1 {
+  void foo(
+      // Prevent formatter from joining the line below to the one above
+      {x} //# 01: compile-time error
+      ) {}
+}
+
+class BaseWithM1 = Base with M1;
+
+class M2 {
+  void foo() {}
+}
+
+class Derived extends BaseWithM1 with M2 {}
+
+main() {
+  new Derived().foo();
+}
diff --git a/tests/language_2/implements_futureor_test.dart b/tests/language_2/implements_futureor_test.dart
new file mode 100644
index 0000000..4e878ff
--- /dev/null
+++ b/tests/language_2/implements_futureor_test.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 'dart:async';
+
+class A<T>
+  implements FutureOr<T> //# 01: compile-time error
+{}
+
+void main() {
+  A a = new A();
+}
diff --git a/tests/language_2/invalid_assignment_to_postfix_increment_test.dart b/tests/language_2/invalid_assignment_to_postfix_increment_test.dart
new file mode 100644
index 0000000..329ea3c
--- /dev/null
+++ b/tests/language_2/invalid_assignment_to_postfix_increment_test.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.
+
+void f(int x, int y) {
+  x++ = y; //# 01: compile-time error
+  x++ += y; //# 02: compile-time error
+  x++ ??= y; //# 03: compile-time error
+}
+
+main() {
+  f(1, 2);
+}
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index 52840b1..1b1cc15 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -2,6 +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.
 
+bug34235_test/01: MissingCompileTimeError # Issue 34235
 mixin_constructor_forwarding/const_constructor_test/none: CompileTimeError # Issue 32223
 mixin_constructor_forwarding/const_constructor_with_field_test/none: CompileTimeError # Issue 32223
 mixin_constructor_forwarding/optional_named_parameters_test/none: CompileTimeError # Issue 31543
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index 469f479..83f9f80 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -27,11 +27,6 @@
 
 [ $compiler == dart2analyzer && $fasta ]
 arg_param_trailing_comma_test/100: Crash # Issue #34043 - Error recovery in outline (extraneous comma before formal parameter)
-arg_param_trailing_comma_test/138: Crash # Error recovery in method body (synthetic argument)
-arg_param_trailing_comma_test/147: Crash # Error recovery in method body (synthetic argument)
-arg_param_trailing_comma_test/156: Crash # Error recovery in method body (synthetic argument)
-arg_param_trailing_comma_test/165: Crash # Error recovery in method body (synthetic argument)
-arg_param_trailing_comma_test/166: Crash # Error recovery in method body (invalid assignment)
 arg_param_trailing_comma_test/24: Crash # Issue #34043 - Error recovery in outline (extraneous comma before formal parameter)
 arg_param_trailing_comma_test/25: Crash # Issue #34043 - Error recovery in outline (extraneous comma before formal parameter)
 arg_param_trailing_comma_test/26: Crash # Issue #34043 - Error recovery in outline (extraneous comma before formal parameter)
@@ -50,6 +45,7 @@
 built_in_identifier_illegal_test/implements: Crash # Issue #34043 - Error recovery in outline (synthetic token used where type expected)
 built_in_identifier_illegal_test/part: Crash # No resolution for a file
 built_in_identifier_illegal_test/typedef: Crash # Issue 33686 - No core library found
+built_in_identifier_type_annotation_test/mixin: Crash # Issue 34164 - mixin support
 built_in_identifier_type_annotation_test/part: Crash # No resolution for a file
 built_in_identifier_type_annotation_test/set: Crash # Issue #34043 - Error recovery in outline
 built_in_identifier_type_annotation_test/set-funret: Crash # Issue #34043 - Error recovery in outline
@@ -58,8 +54,6 @@
 class_cycle2_test/02: Crash # Issue #34043 - Error recovery in outline (class hierarchy cycle - see also #33756)
 class_cycle_test/00: Crash # Issue #34043 - Error recovery in outline (class hierarchy cycle - see also #33756)
 class_cycle_test/01: Crash # Issue #34043 - Error recovery in outline (class hierarchy cycle - see also #33756)
-class_cycle_test/02: MissingCompileTimeError
-class_cycle_test/03: MissingCompileTimeError
 compile_time_constant_static5_test/11: CompileTimeError # Issue 31537
 compile_time_constant_static5_test/16: CompileTimeError # Issue 31537
 compile_time_constant_static5_test/21: CompileTimeError # Issue 31537
@@ -82,9 +76,6 @@
 deferred_load_library_wrong_args_test/01: CompileTimeError # Issue 34047
 duplicate_constructor_test/01: Crash # Issue 33686 - No core library found
 duplicate_field_with_initializer_test/01: Crash # Issue 33686 - No core library found
-duplicate_implements_test/01: MissingCompileTimeError
-duplicate_implements_test/02: MissingCompileTimeError
-duplicate_interface_implements_test/01: MissingCompileTimeError
 dynamic_prefix_core_test/none: CompileTimeError # Issue 34047
 emit_const_fields_test: CompileTimeError # Issue 34047
 enum_syntax_test/02: Crash # Issue #34043 - Error recovery in outline (duplicate enum name)
@@ -139,6 +130,7 @@
 hidden_import_test/02: MissingStaticWarning
 illegal_initializer_test/02: Crash # Issue #33771 - Error recovery in method body (error in constructor initializer)
 illegal_initializer_test/04: Crash # Issue #33771 - Error recovery in method body (error in constructor initializer)
+implements_futureor_test/01: Crash
 import_nonexisting_dart_uri_test/01: Crash # Issue 33686 - No core library found
 instantiate_tearoff_of_call_test: CompileTimeError # Front end fails to instantiate tear-offs of `call`
 instantiate_type_variable_test/01: Crash # Error recovery in method body (attempt to instantiate type variable)
@@ -251,6 +243,7 @@
 prefix_variable_collision_test/01: Crash # Issue 33686 - No core library found
 regress_20394_test/01: Crash # Error recovery in method body (error in super constructor call)
 regress_23408_test: CompileTimeError # Issue 34047
+regress_27617_test/1: Crash # The analyzer doesn't report this error.
 regress_28217_test/01: Crash # Error recovery in method body (error in constructor redirect)
 regress_28217_test/none: Crash # Error recovery in method body (error in constructor redirect)
 regress_29025_test: CompileTimeError # Issue 34047
@@ -278,8 +271,6 @@
 string_supertype_checked_test: CompileTimeError # Issue 34047
 super_bound_closure_test/none: CompileTimeError # Issue 34047
 super_conditional_operator_test/01: Crash # Error recovery in method body (error in constructor redirect)
-super_conditional_operator_test/17: Crash # Error recovery in method body (nonsensical use of super)
-super_conditional_operator_test/18: Crash # Error recovery in method body (nonsensical use of super)
 super_no_such_method1_test: CompileTimeError # Issue 34047
 super_no_such_method2_test: CompileTimeError # Issue 34047
 super_no_such_method3_test: CompileTimeError # Issue 34047
@@ -414,7 +405,6 @@
 accessor_conflict_import_test: CompileTimeError # Issue 25626
 additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568
 built_in_identifier_prefix_test: CompileTimeError
-built_in_identifier_type_annotation_test/dynamic-gen: MissingCompileTimeError # Issue 28813
 cascaded_forwarding_stubs_test: CompileTimeError
 check_member_static_test/01: CompileTimeError
 config_import_corelib_test: CompileTimeError
@@ -422,7 +412,6 @@
 conflicting_generic_interfaces_hierarchy_loop_infinite_test: Skip # Crashes or times out
 const_cast2_test/01: CompileTimeError
 const_cast2_test/none: CompileTimeError
-const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
 constructor9_test/01: MissingCompileTimeError # CFE Issue 33022
 default_implementation2_test: CompileTimeError # Issue 30855
 dynamic_prefix_core_test/01: MissingCompileTimeError
@@ -446,6 +435,7 @@
 generic_no_such_method_dispatcher_test: CompileTimeError
 generic_tearoff_test: CompileTimeError
 getter_setter_in_lib_test: Fail # Issue 23286
+implements_futureor_test/01: MissingCompileTimeError
 implicit_creation/implicit_const_context_constructor_generic_named_test: CompileTimeError
 implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError
 implicit_creation/implicit_const_context_prefix_constructor_generic_named_test: CompileTimeError
@@ -454,10 +444,6 @@
 initializing_formal_final_test: MissingCompileTimeError
 interceptor6_test: CompileTimeError
 interface_test/00: MissingCompileTimeError
-invalid_type_argument_count_test/01: MissingCompileTimeError
-invalid_type_argument_count_test/02: MissingCompileTimeError
-invalid_type_argument_count_test/03: MissingCompileTimeError
-invalid_type_argument_count_test/04: MissingCompileTimeError
 issue13673_test: StaticWarning # Issue 31925
 issue31596_implement_covariant_test: CompileTimeError
 issue31596_override_test/01: CompileTimeError
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 3b91111..ab0f9c8 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -26,7 +26,6 @@
 deopt_inlined_function_lazy_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 deopt_smi_op_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in dart2js; bug #11551.
-duplicate_interface_implements_test/01: MissingCompileTimeError
 external_test/10: CompileTimeError # External non-js-interop function are treated as compile-time errors.
 external_test/13: CompileTimeError # External non-js-interop function are treated as compile-time errors.
 external_test/20: CompileTimeError # External non-js-interop function are treated as compile-time errors.
@@ -256,10 +255,6 @@
 deferred_not_loaded_check_test: RuntimeError # Test out of date. Issue 31933
 deferred_redirecting_factory_test: RuntimeError
 double_int_to_string_test: RuntimeError, OK # non JS number semantics
-duplicate_implements_test/01: MissingCompileTimeError
-duplicate_implements_test/02: MissingCompileTimeError
-duplicate_implements_test/03: MissingCompileTimeError
-duplicate_implements_test/04: MissingCompileTimeError
 dynamic_prefix_core_test/none: RuntimeError
 enum_mirror_test: RuntimeError
 expect_test: RuntimeError, OK # Issue 13080
@@ -545,8 +540,6 @@
 bit_operations_test: RuntimeError
 branch_canonicalization_test: RuntimeError
 canonical_const2_test: RuntimeError, OK # non JS number semantics
-class_cycle_test/02: MissingCompileTimeError
-class_cycle_test/03: MissingCompileTimeError
 compile_time_constant_o_test/01: MissingCompileTimeError
 compile_time_constant_o_test/02: MissingCompileTimeError
 compile_time_constant_static5_test/11: CompileTimeError
@@ -573,8 +566,6 @@
 deferred_not_loaded_check_test: RuntimeError # Test out of date. Issue 31933
 deferred_redirecting_factory_test: RuntimeError
 double_int_to_string_test: RuntimeError, OK # non JS number semantics
-duplicate_implements_test/01: MissingCompileTimeError
-duplicate_implements_test/02: MissingCompileTimeError
 dynamic_prefix_core_test/none: CompileTimeError
 emit_const_fields_test: CompileTimeError
 enum_mirror_test: RuntimeError
@@ -706,7 +697,6 @@
 redirecting_factory_reflection_test: RuntimeError
 regress_23408_test: CompileTimeError
 regress_24283_test: RuntimeError, OK # non JS number semantics
-regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
 regress_28255_test: RuntimeError
 regress_29025_test: CompileTimeError
 regress_29405_test: CompileTimeError
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 858b6af..3098bb5 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -26,7 +26,6 @@
 built_in_identifier_prefix_test: CompileTimeError
 built_in_identifier_type_annotation_test/dynamic-funarg: RuntimeError # Issue 28816
 built_in_identifier_type_annotation_test/dynamic-funret: RuntimeError # Issue 28816
-built_in_identifier_type_annotation_test/dynamic-gen: MissingCompileTimeError # Issue 28816
 built_in_identifier_type_annotation_test/dynamic-list: RuntimeError # Issue 28816
 cascaded_forwarding_stubs_generic_test: RuntimeError
 cascaded_forwarding_stubs_test: CompileTimeError
@@ -37,7 +36,6 @@
 const_cast2_test/none: CompileTimeError
 const_constructor_mixin3_test/01: MissingCompileTimeError # Issue 33644
 const_constructor_mixin_test/01: MissingCompileTimeError # Issue 33644
-const_for_in_variable_test/01: MissingCompileTimeError
 constructor9_test/01: MissingCompileTimeError # CFE Issue 33022
 constructor_type_parameter_test/00: MissingCompileTimeError
 constructor_with_type_parameters_test/03: MissingCompileTimeError
@@ -71,6 +69,7 @@
 generic_no_such_method_dispatcher_test: CompileTimeError
 getter_closure_execution_order_test: RuntimeError # Issue 29920
 getter_setter_in_lib_test: CompileTimeError
+implements_futureor_test/01: MissingCompileTimeError
 implicit_creation/implicit_const_context_constructor_generic_named_test: CompileTimeError
 implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError
 implicit_creation/implicit_const_context_prefix_constructor_generic_named_test: CompileTimeError
@@ -84,10 +83,6 @@
 instantiate_tearoff_of_call_test: RuntimeError
 interface_test/00: MissingCompileTimeError
 internal_library_test/01: MissingCompileTimeError # Issue 29920
-invalid_type_argument_count_test/01: MissingCompileTimeError
-invalid_type_argument_count_test/02: MissingCompileTimeError
-invalid_type_argument_count_test/03: MissingCompileTimeError
-invalid_type_argument_count_test/04: MissingCompileTimeError
 issue31596_implement_covariant_test: CompileTimeError
 issue31596_override_test/01: CompileTimeError
 issue31596_override_test/02: CompileTimeError
@@ -241,8 +236,8 @@
 call_method_implicit_tear_off_implements_function_test/06: RuntimeError # Kernel is missing the implicit `call` tearoff for assignment `Function`
 call_method_must_not_be_field_test/06: RuntimeError # Kernel does not distinguish `d()` from `d.call()`
 call_method_must_not_be_getter_test/06: RuntimeError # Kernel does not distinguish `d()` from `d.call()`
-class_cycle_test/02: MissingCompileTimeError
-class_cycle_test/03: MissingCompileTimeError
+call_non_method_field_test/01: MissingCompileTimeError
+call_non_method_field_test/02: MissingCompileTimeError
 compile_time_constant_c_test/02: MissingCompileTimeError
 compile_time_constant_k_test/01: MissingCompileTimeError
 compile_time_constant_k_test/02: MissingCompileTimeError
@@ -274,9 +269,6 @@
 covariant_subtyping_test: RuntimeError
 deferred_load_library_wrong_args_test/01: CompileTimeError
 double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in ddk
-duplicate_implements_test/01: MissingCompileTimeError
-duplicate_implements_test/02: MissingCompileTimeError
-duplicate_interface_implements_test/01: MissingCompileTimeError
 dynamic_prefix_core_test/none: CompileTimeError
 emit_const_fields_test: CompileTimeError # Issue 31533
 export_ambiguous_main_test: MissingCompileTimeError
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index a0a0476..76a6c49 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -156,11 +156,7 @@
 web_int_literals_test/*: SkipByDesign # Test applies only to JavaScript targets
 
 [ $compiler == dartkp ]
-class_cycle_test/02: MissingCompileTimeError
-class_cycle_test/03: MissingCompileTimeError
 covariant_subtyping_test: RuntimeError
-duplicate_implements_test/01: MissingCompileTimeError
-duplicate_implements_test/02: MissingCompileTimeError
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
 generic_no_such_method_dispatcher_test: RuntimeError # Issue 31424
 web_int_literals_test/*: SkipByDesign # Test applies only to JavaScript targets
@@ -290,7 +286,6 @@
 redirecting_factory_default_values_test/01: MissingCompileTimeError # Issue 34160
 redirecting_factory_default_values_test/02: MissingCompileTimeError # Issue 34160
 regress_22976_test/*: CompileTimeError # Issue 31935
-regress_27617_test/1: MissingCompileTimeError # Issue 34161
 syntax_test/28: MissingCompileTimeError # Issue 29763 - low priority
 syntax_test/29: MissingCompileTimeError # Issue 29763 - low priority
 syntax_test/30: MissingCompileTimeError # Issue 29763 - low priority
@@ -721,6 +716,7 @@
 const_dynamic_type_literal_test/02: Pass
 map_literal3_test/01: Pass
 map_literal3_test/02: Pass
+type_alias_equality_test/02: RuntimeError # Issue 31359
 vm/bool_check_stack_traces_test/01: RuntimeError # No support for line numbers in stacktraces
 vm/bool_check_stack_traces_test/none: RuntimeError # No support for line numbers in stacktraces
 vm/causal_async_exception_stack2_test: RuntimeError # No support for line numbers in stacktraces
@@ -1053,8 +1049,6 @@
 tearoff_dynamic_test: RuntimeError # Compares call to "foo" (noSuchMethod) with string "foo"
 
 [ $compiler == fasta && $strong ]
-class_cycle_test/02: MissingCompileTimeError
-class_cycle_test/03: MissingCompileTimeError
 compile_time_constant_static4_test/02: MissingCompileTimeError
 compile_time_constant_static4_test/03: MissingCompileTimeError
 compile_time_constant_static5_test/11: CompileTimeError
@@ -1068,8 +1062,6 @@
 const_constructor3_test/04: MissingCompileTimeError
 constants_test/05: MissingCompileTimeError
 deferred_load_library_wrong_args_test/01: CompileTimeError
-duplicate_implements_test/01: MissingCompileTimeError
-duplicate_implements_test/02: MissingCompileTimeError
 dynamic_prefix_core_test/none: CompileTimeError
 emit_const_fields_test: CompileTimeError
 export_ambiguous_main_test: MissingCompileTimeError
@@ -1396,7 +1388,7 @@
 enum_test: Crash
 
 [ $mode == debug && ($compiler == dartk || $compiler == dartkb) && ($hot_reload || $hot_reload_rollback) ]
-enum_duplicate_test/01: Crash
+enum_duplicate_test/01: Pass, Crash
 
 [ $mode == product && $runtime == vm && ($compiler == dartk || $compiler == dartkb) ]
 deferred_load_constants_test/02: Fail
@@ -1799,8 +1791,6 @@
 deferred_constraints_type_annotation_test/type_annotation_generic4: MissingCompileTimeError
 deferred_constraints_type_annotation_test/type_annotation_null: MissingCompileTimeError
 deferred_constraints_type_annotation_test/type_annotation_top_level: MissingCompileTimeError
-duplicate_implements_test/01: MissingCompileTimeError
-duplicate_implements_test/02: MissingCompileTimeError
 duplicate_implements_test/03: MissingCompileTimeError
 duplicate_implements_test/04: MissingCompileTimeError
 dynamic_field_test/01: MissingCompileTimeError
@@ -2435,6 +2425,3 @@
 [ $compiler == dartk || $compiler == dartkb || $compiler == dartkp ]
 generic_function_bounds_test: RuntimeError # Issue 32076
 generic_test/01: MissingCompileTimeError
-
-[ $compiler == dartkp || $compiler == fasta ]
-duplicate_interface_implements_test/01: MissingCompileTimeError
diff --git a/tests/language_2/vm/exactness/future_or_regression_34238_test.dart b/tests/language_2/vm/exactness/future_or_regression_34238_test.dart
new file mode 100644
index 0000000..9ee7a96
--- /dev/null
+++ b/tests/language_2/vm/exactness/future_or_regression_34238_test.dart
@@ -0,0 +1,14 @@
+import 'dart:async';
+
+class A {
+  FutureOr<int> x;
+}
+
+Future<int> foo() async => 42;
+
+main() {
+  var a = new A();
+  a.x = 33;
+  a.x = null;
+  a.x = foo();
+}
diff --git a/tests/lib_2/async/stream_from_iterable_test.dart b/tests/lib_2/async/stream_from_iterable_test.dart
index eb254c2..b8317f0 100644
--- a/tests/lib_2/async/stream_from_iterable_test.dart
+++ b/tests/lib_2/async/stream_from_iterable_test.dart
@@ -2,110 +2,127 @@
 // 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 merging streams.
-library dart.test.stream_from_iterable;
+// Test Stream.fromIterable.
 
 import 'dart:async';
 
+import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
 import 'package:expect/async_minitest.dart';
 
 import 'event_helper.dart';
 
-class IterableTest<T> {
-  static int counter = 0;
-  Iterable<T> iterable;
-  IterableTest(this.iterable);
-  void run() {
-    test("stream from iterable ${counter++}", () {
-      Events expected = new Events.fromIterable(iterable);
-      Stream<T> stream = new Stream<T>.fromIterable(iterable);
-      Events actual = new Events.capture(stream);
-      actual.onDone(expectAsync(() {
-        Expect.listEquals(expected.events, actual.events);
-      }));
-    });
-  }
+// Tests that various typed iterables that do not throw creates
+// suitable streams.
+void iterableTest<T>(Iterable<T> iterable) {
+  asyncStart();
+  List<T> expected = iterable.toList();
+  Stream<T> stream = new Stream<T>.fromIterable(iterable);
+  var events = <T>[];
+  stream.listen(events.add, onDone: () {
+    Expect.listEquals(expected, events, "fromIterable $iterable");
+    asyncEnd();
+  });
 }
 
 main() {
-  new IterableTest([]).run();
-  new IterableTest([1]).run();
-  new IterableTest([1, "two", true, null]).run();
-  new IterableTest<int>([1, 2, 3, 4]).run();
-  new IterableTest<String>(["one", "two", "three", "four"]).run();
-  new IterableTest<int>(new Iterable<int>.generate(1000, (i) => i)).run();
-  new IterableTest<String>(
-      new Iterable<int>.generate(1000, (i) => i).map((i) => "$i")).run();
+  asyncStart();
+
+  iterableTest<Object>(<Object>[]);
+  iterableTest<Null>(<Null>[]);
+  iterableTest<Object>(<int>[1]);
+  iterableTest<Object>(<Object>[1, "two", true, null]);
+  iterableTest<int>(<int>[1, 2, 3, 4]);
+  iterableTest<String>(<String>["one", "two", "three", "four"]);
+  iterableTest<int>(new Iterable<int>.generate(1000, (i) => i));
+  iterableTest<String>(
+      new Iterable<int>.generate(1000, (i) => i).map((i) => "$i"));
 
   Iterable<int> iter = new Iterable.generate(25, (i) => i * 2);
 
-  test("iterable-toList", () {
-    new Stream.fromIterable(iter).toList().then(expectAsync((actual) {
+  {
+    // Test that the stream's .toList works.
+    asyncStart();
+    new Stream.fromIterable(iter).toList().then((actual) {
       List expected = iter.toList();
       Expect.equals(25, expected.length);
       Expect.listEquals(expected, actual);
-    }));
-  });
+      asyncEnd();
+    });
+  }
 
-  test("iterable-mapped-toList", () {
-    new Stream.fromIterable(iter)
-        .map((i) => i * 3)
-        .toList()
-        .then(expectAsync((actual) {
+  {
+    // Test that the stream's .map works.
+    asyncStart();
+    new Stream.fromIterable(iter).map((i) => i * 3).toList().then((actual) {
       List expected = iter.map((i) => i * 3).toList();
       Expect.listEquals(expected, actual);
-    }));
-  });
+      asyncEnd();
+    });
+  }
 
-  test("iterable-paused", () {
-    var stream = new Stream<int>.fromIterable(iter);
-    Events actual = new Events();
+  {
+    // Test that pause works.
+    asyncStart();
+    int ctr = 0;
+
+    var stream = new Stream<int>.fromIterable(iter.map((x) {
+      ctr++;
+      return x;
+    }));
+
     StreamSubscription subscription;
+    var actual = [];
     subscription = stream.listen((int value) {
       actual.add(value);
       // Do a 10 ms pause during the playback of the iterable.
       Duration duration = const Duration(milliseconds: 10);
       if (value == 20) {
-        subscription.pause(new Future.delayed(duration, () {}));
+        asyncStart();
+        int beforeCtr = ctr;
+        subscription.pause(new Future.delayed(duration, () {}).whenComplete(() {
+          Expect.equals(beforeCtr, ctr);
+          asyncEnd();
+        }));
       }
-    }, onDone: expectAsync(() {
-      actual.close();
-      Events expected = new Events.fromIterable(iter);
-      Expect.listEquals(expected.events, actual.events);
-    }));
-  });
+    }, onDone: () {
+      Expect.listEquals(iter.toList(), actual);
+      asyncEnd();
+    });
+  }
 
-  test("iterable-single-subscription", () {
+  {
+    // Test that you can't listen twice..
     Stream stream = new Stream.fromIterable(iter);
-    stream.listen((x) {});
-    Expect.throwsStateError(() => stream.listen((x) {}));
-  });
+    stream.listen((x) {}).cancel();
+    Expect.throws<StateError>(() => stream.listen((x) {}));
+  }
 
-  test("regression-14332", () {
+  {
     // Regression test for http://dartbug.com/14332.
-    // This should succeede.
+    // This should succeed.
     var from = new Stream.fromIterable([1, 2, 3, 4, 5]);
 
     var c = new StreamController();
     var sink = c.sink;
 
-    var done = expectAsync(() {}, count: 2);
+    asyncStart(2);
 
     // if this goes first, test failed (hanged). Swapping addStream and toList
     // made failure go away.
     sink.addStream(from).then((_) {
       c.close();
-      done();
+      asyncEnd();
     });
 
     c.stream.toList().then((x) {
       Expect.listEquals([1, 2, 3, 4, 5], x);
-      done();
+      asyncEnd();
     });
-  });
+  }
 
-  test("regression-14334-b", () {
+  {
+    // Regression test for issue 14334 (#2)
     var from = new Stream.fromIterable([1, 2, 3, 4, 5]);
 
     // odd numbers as data events, even numbers as error events
@@ -113,17 +130,128 @@
 
     var c = new StreamController();
 
-    var done = expectAsync(() {}, count: 2);
+    asyncStart();
 
     var data = [], errors = [];
     c.stream.listen(data.add, onError: errors.add, onDone: () {
       Expect.listEquals([1, 3, 5], data);
       Expect.listEquals([2, 4], errors);
-      done();
+      asyncEnd();
     });
     c.addStream(from).then((_) {
       c.close();
-      done();
     });
+  }
+
+  {
+    // Example from issue http://dartbug.com/33431.
+    asyncStart();
+    var asyncStarStream = () async* {
+      yield 1;
+      yield 2;
+      throw "bad";
+    }();
+    collectEvents(asyncStarStream).then((events2) {
+      Expect.listEquals(["value", 1, "value", 2, "error", "bad"], events2);
+      asyncEnd();
+    });
+
+    Iterable<int> throwingIterable() sync* {
+      yield 1;
+      yield 2;
+      throw "bad";
+    }
+
+    // Sanity check behavior.
+    var it = throwingIterable().iterator;
+    Expect.isTrue(it.moveNext());
+    Expect.equals(1, it.current);
+    Expect.isTrue(it.moveNext());
+    Expect.equals(2, it.current);
+    Expect.throws(it.moveNext, (e) => e == "bad");
+
+    asyncStart();
+    var syncStarStream = new Stream<int>.fromIterable(throwingIterable());
+    collectEvents(syncStarStream).then((events1) {
+      Expect.listEquals(["value", 1, "value", 2, "error", "bad"], events1);
+      asyncEnd();
+    });
+  }
+
+  {
+    // Test error behavior. Changed when fixing issue 33431.
+    // Iterable where "current" throws for third value, moveNext on fifth call.
+    var m = new MockIterable<int>((n) {
+      return n != 5 || (throw "moveNext");
+    }, (n) {
+      return n != 3 ? n : throw "current";
+    });
+    asyncStart();
+    collectEvents(new Stream<int>.fromIterable(m)).then((events) {
+      // Error on "current" does not stop iteration.
+      // Error on "moveNext" does.
+      Expect.listEquals([
+        "value",
+        1,
+        "value",
+        2,
+        "error",
+        "current",
+        "value",
+        4,
+        "error",
+        "moveNext"
+      ], events);
+      asyncEnd();
+    });
+  }
+
+  asyncEnd();
+}
+
+// Collects value and error events in a list.
+// Value events preceeded by "value", error events by "error".
+// Completes on done event.
+Future<List<Object>> collectEvents(Stream<Object> stream) {
+  var c = new Completer<List<Object>>();
+  var events = <Object>[];
+  stream.listen((value) {
+    events..add("value")..add(value);
+  }, onError: (error) {
+    events..add("error")..add(error);
+  }, onDone: () {
+    c.complete(events);
   });
+  return c.future;
+}
+
+// Mock iterable.
+// A `MockIterable<T>(f1, f2)` calls `f1` on `moveNext` calls with incrementing
+// values starting from 1. Calls `f2` on `current` access, with the same integer
+// as the most recent `f1` call.
+class MockIterable<T> extends Iterable<T> {
+  final bool Function(int) _onMoveNext;
+  final T Function(int) _onCurrent;
+
+  MockIterable(this._onMoveNext, this._onCurrent);
+
+  Iterator<T> get iterator => MockIterator(_onMoveNext, _onCurrent);
+}
+
+class MockIterator<T> implements Iterator<T> {
+  final bool Function(int) _onMoveNext;
+  final T Function(int) _onCurrent;
+
+  int _counter = 0;
+
+  MockIterator(this._onMoveNext, this._onCurrent);
+
+  bool moveNext() {
+    _counter += 1;
+    return _onMoveNext(_counter);
+  }
+
+  T get current {
+    return _onCurrent(_counter);
+  }
 }
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index 7db464c..f7529d1 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -121,6 +121,7 @@
 [ !$strong ]
 async/future_test: SkipByDesign # Uses Dart 2 syntax.
 async/stream_first_where_test/badType: MissingCompileTimeError
+async/stream_from_iterable_test: SkipByDesign # Uses Dart 2 syntax.
 async/stream_last_where_test/badType: MissingCompileTimeError
 mirrors/redirecting_factory_different_type_test/02: MissingCompileTimeError
 
diff --git a/tests/lib_2/lib_2_vm.status b/tests/lib_2/lib_2_vm.status
index 485c54e..8a82ed2 100644
--- a/tests/lib_2/lib_2_vm.status
+++ b/tests/lib_2/lib_2_vm.status
@@ -59,7 +59,6 @@
 async/schedule_microtask5_test: RuntimeError
 async/stream_controller_async_test: RuntimeError
 async/stream_first_where_test: RuntimeError
-async/stream_from_iterable_test: RuntimeError
 async/stream_iterator_test: RuntimeError
 async/stream_join_test: RuntimeError
 async/stream_last_where_test: RuntimeError
diff --git a/tools/VERSION b/tools/VERSION
index 6f56b53..f2c3b69 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 1
 PATCH 0
-PRERELEASE 2
+PRERELEASE 3
 PRERELEASE_PATCH 0
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index b7c5551..9e5670f 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -77,8 +77,6 @@
       -- \
       third_party/d8/linux/ia32/natives_blob.bin \
       third_party/d8/linux/ia32/snapshot_blob.bin \
-      out/ReleaseIA32/vm_outline.dill \
-      out/ReleaseIA32/vm_platform.dill \
       out/ReleaseIA32/vm_outline_strong.dill \
       out/ReleaseIA32/vm_platform_strong.dill \
       third_party/firefox_jsshell/linux/ \
@@ -178,8 +176,6 @@
       -- \
       third_party/d8/linux/ia32/natives_blob.bin \
       third_party/d8/linux/ia32/snapshot_blob.bin \
-      out/ReleaseIA32/vm_outline.dill \
-      out/ReleaseIA32/vm_platform.dill \
       out/ReleaseIA32/vm_outline_strong.dill \
       out/ReleaseIA32/vm_platform_strong.dill \
       third_party/firefox_jsshell/linux/ \
@@ -244,8 +240,6 @@
       -- \
       third_party/d8/linux/x64/natives_blob.bin \
       third_party/d8/linux/x64/snapshot_blob.bin \
-      out/ReleaseX64/vm_outline.dill \
-      out/ReleaseX64/vm_platform.dill \
       out/ReleaseX64/vm_outline_strong.dill \
       out/ReleaseX64/vm_platform_strong.dill \
       out/ReleaseX64/dart-sdk \
@@ -367,8 +361,6 @@
       -- \
       third_party/d8/linux/x64/natives_blob.bin \
       third_party/d8/linux/x64/snapshot_blob.bin \
-      out/ReleaseX64/vm_outline.dill \
-      out/ReleaseX64/vm_platform.dill \
       out/ReleaseX64/vm_outline_strong.dill \
       out/ReleaseX64/vm_platform_strong.dill \
       out/ReleaseX64/dart-sdk \
@@ -415,12 +407,10 @@
     out/ReleaseX64/dart pkg/analysis_server/benchmark/benchmarks.dart run --quick --repeat 1 analysis-server-cold
     out/ReleaseX64/dart --print_metrics pkg/analyzer_cli/bin/analyzer.dart --dart-sdk=sdk hello.dart
     echo '[{"name":"foo","edits":[["pkg/compiler/lib/src/dart2js.dart","2016","2017"],["pkg/compiler/lib/src/options.dart","2016","2017"]]}]' > appjit_train_edits.json
-    out/ReleaseX64/dart --background-compilation=false --snapshot-kind=app-jit --snapshot=pkg/front_end/tool/incremental_perf.dart.appjit pkg/front_end/tool/incremental_perf.dart --target=vm --sdk-summary=out/ReleaseX64/vm_platform.dill --sdk-library-specification=sdk/lib/libraries.json pkg/compiler/lib/src/dart2js.dart appjit_train_edits.json
+    out/ReleaseX64/dart --background-compilation=false --snapshot-kind=app-jit --snapshot=pkg/front_end/tool/incremental_perf.dart.appjit pkg/front_end/tool/incremental_perf.dart --target=vm --sdk-summary=out/ReleaseX64/vm_platform_strong.dill --sdk-library-specification=sdk/lib/libraries.json pkg/compiler/lib/src/dart2js.dart appjit_train_edits.json
     out/ReleaseX64/dart --background-compilation=false pkg/front_end/tool/incremental_perf.dart.appjit --target=vm --sdk-summary=out/ReleaseX64/vm_platform_strong.dill --sdk-library-specification=sdk/lib/libraries.json pkg/front_end/benchmarks/ikg/hello.dart pkg/front_end/benchmarks/ikg/hello.edits.json
-    out/ReleaseX64/dart --background-compilation=false pkg/front_end/tool/incremental_perf.dart.appjit --target=vm --mode=legacy --sdk-summary=out/ReleaseX64/vm_platform.dill --sdk-library-specification=sdk/lib/libraries.json pkg/front_end/benchmarks/ikg/hello.dart pkg/front_end/benchmarks/ikg/hello.edits.json
     out/ReleaseX64/dart --background-compilation=false pkg/front_end/tool/incremental_perf.dart.appjit --target=vm --implementation=minimal --sdk-summary=out/ReleaseX64/vm_platform_strong.dill --sdk-library-specification=sdk/lib/libraries.json pkg/front_end/benchmarks/ikg/hello.dart pkg/front_end/benchmarks/ikg/hello.edits.json
-    out/ReleaseX64/dart --background-compilation=false pkg/front_end/tool/incremental_perf.dart.appjit --target=vm --mode=legacy --implementation=minimal --sdk-summary=out/ReleaseX64/vm_platform.dill --sdk-library-specification=sdk/lib/libraries.json pkg/front_end/benchmarks/ikg/hello.dart pkg/front_end/benchmarks/ikg/hello.edits.json
-    out/ReleaseX64/dart --packages=.packages pkg/kernel/test/binary_bench.dart --golem AstFromBinaryLazy out/ReleaseX64/vm_platform.dill
+    out/ReleaseX64/dart --packages=.packages pkg/kernel/test/binary_bench.dart --golem AstFromBinaryLazy out/ReleaseX64/vm_platform_strong.dill
     cd ..
     rm -rf tmp
   else
diff --git a/utils/application_snapshot.gni b/utils/application_snapshot.gni
index e8e6d35..b225d40 100644
--- a/utils/application_snapshot.gni
+++ b/utils/application_snapshot.gni
@@ -143,7 +143,7 @@
       deps = []
     }
     deps += [
-      "$_dart_root/utils/kernel-service:kernel-service_snapshot"
+      "$_dart_root/utils/kernel-service:kernel-service"
     ]
   }
 }