Version 2.6.0-dev.5.0

Merge commit '5c106e3098bb64139e6c91cd5a57b82bbe662111' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec7b523..81f49ec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,16 +31,20 @@
 
 #### Linter
 
-The Linter was updated to `0.1.98`, which includes:
+The Linter was updated to `0.1.99`, which includes:
 
-* fixed null raw expression accesses in `use_to_and_as_if_applicable`
-* internal migration to using analyzer `InheritanceManager3`
-* internal migration away from using analyzer `resolutionMap`
-* various fixes and improvements to anticipate support for extension-methods
-* new lint: `camel_case_extensions`
-* rule template generation improvements
-* new lint: `avoid_equals_and_hash_code_on_mutable_classes`
-* extended `avoid_slow_async_io` to flag async `Directory` methods
+* fixed unsafe casts in `overridden_fields`
+* (internal) migration to the mock SDK in `package:analyzer` for testing
+* fixed empty argument list access in `use_full_hex_values_for_flutter_color_fix`
+* new lint: `prefer_relative_imports`
+* improved messages for `await_only_futures`
+
+## 2.5.1 - 2019-09-27
+
+This is a patch release that prevents type inference failures in the analyzer
+(Issue [38365][]).
+
+[38365]: https://github.com/dart-lang/sdk/issues/38365
 
 ## 2.5.0 - 2019-09-10
 
diff --git a/DEPS b/DEPS
index 60b6900..3090e38 100644
--- a/DEPS
+++ b/DEPS
@@ -99,7 +99,7 @@
   "intl_tag": "0.15.7",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.98",
+  "linter_tag": "0.1.99",
   "logging_tag": "0.11.3+2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_tag": "2.1.1",
@@ -136,7 +136,7 @@
   "test_descriptor_tag": "1.1.1",
   "test_process_tag": "1.0.3",
   "term_glyph_tag": "1.0.1",
-  "test_reflective_loader_tag": "0.1.8",
+  "test_reflective_loader_tag": "0.1.9",
   "test_tag": "test-v1.6.4",
   "tflite_native_rev": "06e533a9747306d1114c53427cc67eda080f51f9",
   "typed_data_tag": "1.1.6",
@@ -174,7 +174,7 @@
   Var("dart_root") + "/tools/sdks": {
       "packages": [{
           "package": "dart/dart-sdk/${{platform}}",
-          "version": "version:2.6.0-dev.3.0",
+          "version": "version:2.6.0-dev.4.0",
       }],
       "dep_type": "cipd",
   },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index abfe139..b7a443f 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -216,18 +216,25 @@
         return []
 
     local_root = input_api.change.RepositoryRoot()
-    layering_check = imp.load_source(
-        'layering_check',
-        os.path.join(local_root, 'runtime', 'tools', 'layering_check.py'))
-    errors = layering_check.DoCheck(local_root)
+    compiler_layering_check = imp.load_source(
+        'compiler_layering_check',
+        os.path.join(local_root, 'runtime', 'tools',
+                     'compiler_layering_check.py'))
+    errors = compiler_layering_check.DoCheck(local_root)
+    embedder_layering_check = imp.load_source(
+        'embedder_layering_check',
+        os.path.join(local_root, 'runtime', 'tools',
+                     'embedder_layering_check.py'))
+    errors += embedder_layering_check.DoCheck(local_root)
     if errors:
         return [
             output_api.PresubmitError(
                 'Layering check violation for C++ sources.',
                 long_text='\n'.join(errors))
         ]
-    else:
-        return []
+
+    return []
+
 
 def _CheckClangTidy(input_api, output_api):
     """Run clang-tidy on VM changes."""
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 109e3fc..e5254c7 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -130,6 +130,10 @@
 
   # Compile for Thread Sanitizer to find threading bugs.
   is_tsan = false
+
+  # Whether to use the NNBD fork of the SDK core libraries.
+  # TODO(rnystrom): Remove this when the fork has been merged back in.
+  use_nnbd = false
 }
 
 # =============================================================================
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index ef4751b..0b33895 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -6,12 +6,13 @@
 import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
 import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
 import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/highlight_css.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/highlight_js.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/info_builder.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_listener.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/highlight_js.dart';
-import 'package:analysis_server/src/edit/nnbd_migration/highlight_css.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/file_system/file_system.dart';
@@ -216,30 +217,46 @@
 
   /// Generate output into the given [folder].
   void _generateOutput(OverlayResourceProvider provider, Folder folder) async {
-    List<LibraryInfo> libraryInfos =
-        await InfoBuilder(instrumentationListener.data, listener)
-            .explainMigration();
+    // Remove any previously generated output.
+    folder.getChildren().forEach((resource) => resource.delete());
+    // Gather the data needed in order to produce the output.
+    InfoBuilder infoBuilder =
+        InfoBuilder(instrumentationListener.data, listener);
+    List<UnitInfo> unitInfos = await infoBuilder.explainMigration();
     var pathContext = provider.pathContext;
     MigrationInfo migrationInfo =
-        MigrationInfo(libraryInfos, pathContext, includedRoot);
-    for (LibraryInfo info in libraryInfos) {
-      assert(info.units.isNotEmpty);
-      String libraryPath =
-          pathContext.setExtension(info.units.first.path, '.html');
-      String relativePath =
-          pathContext.relative(libraryPath, from: includedRoot);
-      List<String> directories =
-          pathContext.split(pathContext.dirname(relativePath));
-      for (int i = 0; i < directories.length; i++) {
-        String directory = pathContext.joinAll(directories.sublist(0, i + 1));
-        folder.getChildAssumingFolder(directory).create();
-      }
-      File output =
-          provider.getFile(pathContext.join(folder.path, relativePath));
-      String rendered = InstrumentationRenderer(info, migrationInfo).render();
+        MigrationInfo(unitInfos, pathContext, includedRoot);
+    PathMapper pathMapper = PathMapper(provider, folder.path, includedRoot);
+
+    /// Produce output for the compilation unit represented by the [unitInfo].
+    void render(UnitInfo unitInfo) {
+      File output = provider.getFile(pathMapper.map(unitInfo.path));
+      output.parent.create();
+      String rendered =
+          InstrumentationRenderer(unitInfo, migrationInfo, pathMapper).render();
       output.writeAsStringSync(rendered);
     }
-    // Generate resource files:
+
+    // Generate the files in the package being migrated.
+    for (UnitInfo unitInfo in unitInfos) {
+      render(unitInfo);
+    }
+    // Generate other dart files.
+    for (UnitInfo unitInfo in infoBuilder.unitMap.values) {
+      if (!unitInfos.contains(unitInfo)) {
+        if (unitInfo.content == null) {
+          try {
+            unitInfo.content =
+                provider.getFile(unitInfo.path).readAsStringSync();
+          } catch (_) {
+            // If we can't read the content of the file, then skip it.
+            continue;
+          }
+        }
+        render(unitInfo);
+      }
+    }
+    // Generate resource files.
     File highlightJsOutput =
         provider.getFile(pathContext.join(folder.path, 'highlight.pack.js'));
     highlightJsOutput.writeAsStringSync(decodeHighlightJs());
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
index 694a210..950e06f 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/info_builder.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/domains/analysis/navigation_dart.dart';
 import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_information.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
@@ -10,9 +11,12 @@
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/dart/analysis/session.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     show Location, SourceEdit, SourceFileEdit;
+import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
+import 'package:analyzer_plugin/src/utilities/navigation/navigation.dart';
 import 'package:nnbd_migration/instrumentation.dart';
 import 'package:nnbd_migration/nnbd_migration.dart';
 
@@ -48,20 +52,60 @@
 
   /// Return the migration information for all of the libraries that were
   /// migrated.
-  Future<List<LibraryInfo>> explainMigration() async {
-    Map<Source, SourceInformation> sourceInfo = info.sourceInformation;
-    List<LibraryInfo> libraries = [];
-    for (Source source in sourceInfo.keys) {
+  Future<List<UnitInfo>> explainMigration() async {
+    Map<Source, SourceInformation> sourceInfoMap = info.sourceInformation;
+    List<UnitInfo> units = [];
+    for (Source source in sourceInfoMap.keys) {
       String filePath = source.fullName;
       AnalysisSession session =
           server.getAnalysisDriver(filePath).currentSession;
       if (!session.getFile(filePath).isPart) {
-        ParsedLibraryResult result = await session.getParsedLibrary(filePath);
-        libraries
-            .add(_explainLibrary(result, info, sourceInfo[source], listener));
+        ResolvedLibraryResult result =
+            await session.getResolvedLibrary(filePath);
+        SourceInformation sourceInfo = sourceInfoMap[source];
+        for (ResolvedUnitResult unitResult in result.units) {
+          SourceFileEdit edit =
+              listener.sourceChange.getFileEdit(unitResult.path);
+          units.add(_explainUnit(sourceInfo, unitResult, edit));
+        }
       }
     }
-    return libraries;
+    return units;
+  }
+
+  /// Return details for a fix built from the given [edge], or `null` if the
+  /// edge does not have an origin.
+  String _buildDescriptionForDestination(AstNode node) {
+    // Other found types:
+    // - ConstructorDeclaration
+    if (node.parent is FormalParameterList) {
+      return "A nullable value can't be passed as an argument";
+    } else {
+      return "A nullable value can't be used here";
+    }
+  }
+
+  /// Return details for a fix built from the given [edge], or `null` if the
+  /// edge does not have an origin.
+  String _buildDescriptionForOrigin(AstNode node) {
+    String /*!*/ description;
+    if (node.parent is ArgumentList) {
+      if (node is NullLiteral) {
+        description = "An explicit 'null' is passed as an argument";
+      } else {
+        description = "A nullable value is explicitly passed as an argument";
+      }
+    } else {
+      if (node is NullLiteral) {
+        description = "An explicit 'null' is assigned";
+      } else {
+        description = "A nullable value is assigned";
+      }
+    }
+    if (_inTestCode(node)) {
+      description += " in test code";
+    }
+    return description;
   }
 
   /// Compute the details for the fix with the given [fixInfo].
@@ -70,28 +114,26 @@
     for (FixReasonInfo reason in fixInfo.reasons) {
       if (reason is NullabilityNodeInfo) {
         for (EdgeInfo edge in reason.upstreamEdges) {
-          EdgeOriginInfo origin = info.edgeOrigin[edge];
-          if (origin != null) {
-            AstNode node = origin.node;
-            if (node.parent is ArgumentList) {
-              if (node is NullLiteral) {
-                details.add(RegionDetail(
-                    'null is explicitly passed as an argument.',
-                    _targetFor(origin)));
-              } else {
-                details.add(RegionDetail(
-                    'A nullable value is explicitly passed as an argument.',
-                    _targetFor(origin)));
-              }
-            } else {
-              details.add(RegionDetail(
-                  'A nullable value is assigned.', _targetFor(origin)));
+          if (edge.isTriggered) {
+            EdgeOriginInfo origin = info.edgeOrigin[edge];
+            if (origin != null) {
+              // TODO(brianwilkerson) If the origin is an InheritanceOrigin then
+              //  the node is the method declaration in the subclass and we want
+              //  to link to the corresponding parameter in the declaration in
+              //  the superclass.
+              details.add(RegionDetail(_buildDescriptionForOrigin(origin.node),
+                  _targetForNode(origin.source.fullName, origin.node)));
             }
           }
         }
       } else if (reason is EdgeInfo) {
-        // TODO(brianwilkerson) Implement this after finding an example whose
-        //  reason is an edge.
+        NullabilityNodeInfo destination = reason.destinationNode;
+        var nodeInfo = info.nodeInfoFor(destination);
+        if (nodeInfo != null) {
+          details.add(RegionDetail(
+              _buildDescriptionForDestination(nodeInfo.astNode),
+              _targetForNode(nodeInfo.filePath, nodeInfo.astNode)));
+        }
       } else {
         throw UnimplementedError(
             'Unexpected class of reason: ${reason.runtimeType}');
@@ -100,24 +142,41 @@
     return details;
   }
 
-  /// Return the migration information for the given library.
-  LibraryInfo _explainLibrary(
-      ParsedLibraryResult result,
-      InstrumentationInformation info,
-      SourceInformation sourceInfo,
-      DartFixListener listener) {
-    List<UnitInfo> units = [];
-    for (ParsedUnitResult unit in result.units) {
-      SourceFileEdit edit = listener.sourceChange.getFileEdit(unit.path);
-      units.add(_explainUnit(sourceInfo, unit, edit));
-    }
-    return LibraryInfo(units);
+  /// Return the navigation sources for the unit associated with the [result].
+  List<NavigationSource> _computeNavigationSources(ResolvedUnitResult result) {
+    NavigationCollectorImpl collector = new NavigationCollectorImpl();
+    computeDartNavigation(
+        result.session.resourceProvider, collector, result.unit, null, null);
+    collector.createRegions();
+    List<String> files = collector.files;
+    List<protocol.NavigationRegion> regions = collector.regions;
+    List<protocol.NavigationTarget> rawTargets = collector.targets;
+    List<NavigationTarget> convertedTargets =
+        List<NavigationTarget>(rawTargets.length);
+    return regions.map((region) {
+      List<int> targets = region.targets;
+      if (targets.isEmpty) {
+        throw StateError('Targets is empty');
+      }
+      NavigationTarget target = convertedTargets[targets[0]];
+      if (target == null) {
+        protocol.NavigationTarget rawTarget = rawTargets[targets[0]];
+        target = _targetFor(
+            files[rawTarget.fileIndex], rawTarget.offset, rawTarget.length);
+        convertedTargets[targets[0]] = target;
+      }
+      return NavigationSource(region.offset, region.length, target);
+    }).toList();
   }
 
-  /// Return the migration information for the given unit.
-  UnitInfo _explainUnit(SourceInformation sourceInfo, ParsedUnitResult result,
+  /// Return the migration information for the unit associated with the
+  /// [result].
+  UnitInfo _explainUnit(SourceInformation sourceInfo, ResolvedUnitResult result,
       SourceFileEdit fileEdit) {
     UnitInfo unitInfo = _unitForPath(result.path);
+    if (unitInfo.sources == null) {
+      unitInfo.sources = _computeNavigationSources(result);
+    }
     String content = result.content;
     // [fileEdit] is null when a file has no edits.
     if (fileEdit != null) {
@@ -166,17 +225,35 @@
     return null;
   }
 
-  /// Return the navigation target corresponding to the given [origin].
-  NavigationTarget _targetFor(EdgeOriginInfo origin) {
-    AstNode node = origin.node;
-    String filePath = origin.source.fullName;
+  /// Return `true` if the given [node] is from a compilation unit within the
+  /// 'test' directory of the package.
+  bool _inTestCode(AstNode node) {
+    // TODO(brianwilkerson) Generalize this.
+    CompilationUnit unit = node.thisOrAncestorOfType<CompilationUnit>();
+    CompilationUnitElement unitElement = unit?.declaredElement;
+    if (unitElement == null) {
+      return false;
+    }
+    String filePath = unitElement.source.fullName;
+    var resourceProvider = unitElement.session.resourceProvider;
+    return resourceProvider.pathContext.split(filePath).contains('test');
+  }
+
+  /// Return the navigation target in the file with the given [filePath] at the
+  /// given [offset] ans with the given [length].
+  NavigationTarget _targetFor(String filePath, int offset, int length) {
     UnitInfo unitInfo = _unitForPath(filePath);
-    NavigationTarget target =
-        NavigationTarget(filePath, node.offset, node.length);
+    NavigationTarget target = NavigationTarget(filePath, offset, length);
     unitInfo.targets.add(target);
     return target;
   }
 
+  /// Return the navigation target corresponding to the given [node] in the file
+  /// with the given [filePath].
+  NavigationTarget _targetForNode(String filePath, AstNode node) {
+    return _targetFor(filePath, node.offset, node.length);
+  }
+
   /// Return the unit info for the file at the given [path].
   UnitInfo _unitForPath(String path) {
     return unitMap.putIfAbsent(path, () => UnitInfo(path));
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
index 1e60891..e1b1938 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_information.dart
@@ -34,6 +34,55 @@
 
   /// Initialize a newly created holder of instrumentation information.
   InstrumentationInformation();
+
+  /// Return information about the given [node].
+  NodeInformation nodeInfoFor(NullabilityNodeInfo node) {
+    for (MapEntry<Source, SourceInformation> sourceEntry
+        in sourceInformation.entries) {
+      SourceInformation sourceInfo = sourceEntry.value;
+      for (MapEntry<AstNode, DecoratedTypeInfo> entry
+          in sourceInfo.implicitReturnType.entries) {
+        if (entry.value.node == node) {
+          return NodeInformation(
+              sourceEntry.key.fullName, entry.key, entry.value);
+        }
+      }
+      for (MapEntry<AstNode, DecoratedTypeInfo> entry
+          in sourceInfo.implicitType.entries) {
+        if (entry.value.node == node) {
+          return NodeInformation(
+              sourceEntry.key.fullName, entry.key, entry.value);
+        }
+      }
+      for (MapEntry<AstNode, List<DecoratedTypeInfo>> entry
+          in sourceInfo.implicitTypeArguments.entries) {
+        for (var type in entry.value) {
+          if (type.node == node) {
+            return NodeInformation(sourceEntry.key.fullName, entry.key, type);
+          }
+        }
+      }
+    }
+    // The loop below doesn't help because we still don't have access to an AST
+    // node.
+//    for (MapEntry<Element, DecoratedTypeInfo> entry in externalDecoratedType.entries) {
+//      if (entry.value.node == node) {
+//        return NodeInformation(null, null, entry.value);
+//      }
+//    }
+    return null;
+  }
+}
+
+/// The instrumentation information about a [NullabilityNodeInfo].
+class NodeInformation {
+  final String filePath;
+
+  final AstNode astNode;
+
+  final DecoratedTypeInfo decoratedType;
+
+  NodeInformation(this.filePath, this.astNode, this.decoratedType);
 }
 
 /// The instrumentation information gathered from the migration engine that is
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
index 6735746..7e3812a 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/instrumentation_renderer.dart
@@ -1,137 +1,45 @@
+// Copyright (c) 2019, 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:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/offset_mapper.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
 import 'package:meta/meta.dart';
 import 'package:mustache/mustache.dart' as mustache;
 import 'package:path/path.dart' as path;
 
-/// Instrumentation display output for a library that was migrated to use
-/// non-nullable types.
-class InstrumentationRenderer {
-  /// Display information for a library.
-  final LibraryInfo libraryInfo;
-
-  /// Information for a whole migration, so that libraries can reference each
-  /// other.
-  final MigrationInfo migrationInfo;
-
-  /// Creates an output object for the given library info.
-  InstrumentationRenderer(this.libraryInfo, this.migrationInfo);
-
-  /// Builds an HTML view of the instrumentation information in [libraryInfo].
-  String render() {
-    int previousIndex = 0;
-    Map<String, dynamic> mustacheContext = {
-      'units': <Map<String, dynamic>>[],
-      'links': migrationInfo.libraryLinks(libraryInfo),
-      'highlightJsPath': migrationInfo.highlightJsPath(libraryInfo),
-      'highlightStylePath': migrationInfo.highlightStylePath(libraryInfo),
-    };
-    for (var compilationUnit in libraryInfo.units) {
-      // List of Mustache context for both unmodified and modified regions:
-      //
-      // * 'modified': Whether this region represents modified source, or
-      //   unmodified.
-      // * 'content': The textual content of this region.
-      // * 'explanation': The textual explanation of why the content in this
-      //   region was modified. It will appear in a "tooltip" on hover.
-      //   TODO(srawlins): Support some sort of HTML explanation, with
-      //   hyperlinks to anchors in other source code.
-      List<Map> regions = [];
-      for (var region in compilationUnit.regions) {
-        if (region.offset > previousIndex) {
-          // Display a region of unmodified content.
-          regions.add({
-            'modified': false,
-            'content':
-                compilationUnit.content.substring(previousIndex, region.offset)
-          });
-          previousIndex = region.offset + region.length;
-        }
-        regions.add({
-          'modified': true,
-          'content': compilationUnit.content
-              .substring(region.offset, region.offset + region.length),
-          'explanation': region.explanation,
-        });
-      }
-      if (previousIndex < compilationUnit.content.length) {
-        // Last region of unmodified content.
-        regions.add({
-          'modified': false,
-          'content': compilationUnit.content.substring(previousIndex)
-        });
-      }
-      mustacheContext['units']
-          .add({'path': compilationUnit.path, 'regions': regions});
-    }
-    return _template.renderString(mustacheContext);
-  }
-}
-
-/// A class storing rendering information for an entire migration report.
-///
-/// This generally provides one [InstrumentationRenderer] (for one library)
-/// with information about the rest of the libraries represented in the
-/// instrumentation output.
-class MigrationInfo {
-  /// The information about the libraries that are are migrated.
-  final List<LibraryInfo> libraries;
-
-  /// The resource provider's path context.
-  final path.Context pathContext;
-
-  /// The filesystem root used to create relative paths for each unit.
-  final String includedRoot;
-
-  MigrationInfo(this.libraries, this.pathContext, this.includedRoot);
-
-  /// Generate mustache context for library links, for navigation in the
-  /// instrumentation document for [thisLibrary].
-  List<Map<String, Object>> libraryLinks(LibraryInfo thisLibrary) {
-    return [
-      for (var library in libraries)
-        {
-          'name': _computeName(library),
-          'isLink': library != thisLibrary,
-          if (library != thisLibrary)
-            'href': _pathTo(library, source: thisLibrary)
-        }
-    ];
-  }
-
-  /// Return the path to [library] from [includedRoot], to be used as a display
-  /// name for a library.
-  String _computeName(LibraryInfo library) =>
-      pathContext.relative(library.units.first.path, from: includedRoot);
-
-  /// The path to [target], relative to [from].
-  String _pathTo(LibraryInfo target, {@required LibraryInfo source}) {
-    assert(target.units.isNotEmpty);
-    assert(source.units.isNotEmpty);
-    String targetPath =
-        pathContext.setExtension(target.units.first.path, '.html');
-    String sourceDir = pathContext.dirname(source.units.first.path);
-    return pathContext.relative(targetPath, from: sourceDir);
-  }
-
-  /// The path to the highlight.js script, relative to [libraryInfo].
-  String highlightJsPath(LibraryInfo libraryInfo) =>
-      pathContext.relative(pathContext.join(includedRoot, 'highlight.pack.js'),
-          from: pathContext.dirname(libraryInfo.units.first.path));
-
-  /// The path to the highlight.js stylesheet, relative to [libraryInfo].
-  String highlightStylePath(LibraryInfo libraryInfo) =>
-      pathContext.relative(pathContext.join(includedRoot, 'androidstudio.css'),
-          from: pathContext.dirname(libraryInfo.units.first.path));
-}
-
 /// A mustache template for one library's instrumentation output.
 mustache.Template _template = mustache.Template(r'''
 <html>
   <head>
     <title>Non-nullable fix instrumentation report</title>
-    <script src="{{ highlightJsPath }}"></script>
+<!--    <script src="{{ highlightJsPath }}"></script>-->
+    <script>
+    function highlightTarget() {
+      var url = document.URL;
+      var index = url.lastIndexOf("#");
+      if (index >= 0) {
+        var name = url.substring(index + 1);
+        var anchor = document.getElementById(name);
+        if (anchor != null) {
+          anchor.className = "target";
+        }
+      }
+    }
+    </script>
     <link rel="stylesheet" href="{{ highlightStylePath }}">
     <style>
+a:link {
+  color: #000000;
+  text-decoration-line: none;
+}
+
+a:visited {
+  color: #000000;
+  text-decoration-line: none;
+}
+
 body {
   font-family: sans-serif;
   padding: 1em;
@@ -142,6 +50,12 @@
   font-weight: bold;
 }
 
+.code {
+  position: absolute;
+  left: 0.5em;
+  top: 0.5em;
+}
+
 .content {
   font-family: monospace;
   position: relative;
@@ -181,16 +95,22 @@
   top: 100%;
   visibility: hidden;
   white-space: normal;
-  width: 200px;
+  width: 400px;
   z-index: 1;
 }
 
 .region:hover .tooltip {
   visibility: visible;
 }
+
+.target {
+  background-color: #FFFFFF;
+  position: relative;
+  visibility: visible;
+}
     </style>
   </head>
-  <body>
+  <body onload="highlightTarget()">
     <h1>Non-nullable fix instrumentation report</h1>
     <p><em>Well-written introduction to this report.</em></p>
     <div class="navigation">
@@ -203,20 +123,30 @@
     {{# units }}'''
     '<h2>{{{ path }}}</h2>'
     '<div class="content">'
-    '<div class="highlighting">'
-    '{{! These regions are written out, unmodified, as they need to be found }}'
-    '{{! in one simple text string for highlight.js to hightlight them. }}'
-    '{{# regions }}'
-    '{{ content }}'
-    '{{/ regions }}'
+//    '<div class="highlighting">'
+//    '{{! These regions are written out, unmodified, as they need to be found }}'
+//    '{{! in one simple text string for highlight.js to hightlight them. }}'
+//    '{{# regions }}'
+//    '{{ content }}'
+//    '{{/ regions }}'
+//    '</div>'
+    '<div class ="code">'
+    '{{! Write the file content, modified to include navigation information, }}'
+    '{{! both anchors and links. }}'
+    '{{{ navContent }}}'
     '</div>'
     '<div class="regions">'
-    '{{! The regions are then printed again, overlaying the first copy of the }}'
-    '{{! content, to provide tooltips for modified regions. }}'
+    '{{! The regions are then written again, overlaying the first two copies }}'
+    '{{! of the content, to provide tooltips for modified regions. }}'
     '{{# regions }}'
     '{{^ modified }}{{ content }}{{/ modified }}'
     '{{# modified }}<span class="region">{{ content }}'
-    '<span class="tooltip">{{explanation}}</span></span>{{/ modified }}'
+    '<span class="tooltip">{{ explanation }}<ul>'
+    '{{# details }}'
+    '<li>'
+    '<a href="{{ target }}">{{ description }}</a>'
+    '</li>'
+    '{{/ details }}</ul></span></span>{{/ modified }}'
     '{{/ regions }}'
     '</div></div>'
     r'''
@@ -230,3 +160,217 @@
     </script>
   </body>
 </html>''');
+
+/// Instrumentation display output for a library that was migrated to use
+/// non-nullable types.
+class InstrumentationRenderer {
+  /// Display information for a compilation unit.
+  final UnitInfo unitInfo;
+
+  /// Information for a whole migration, so that libraries can reference each
+  /// other.
+  final MigrationInfo migrationInfo;
+
+  /// An object used to map the file paths of analyzed files to the file paths
+  /// of the HTML files used to view the content of those files.
+  final PathMapper pathMapper;
+
+  /// Creates an output object for the given library info.
+  InstrumentationRenderer(this.unitInfo, this.migrationInfo, this.pathMapper);
+
+  /// Builds an HTML view of the instrumentation information in [unitInfo].
+  String render() {
+    Map<String, dynamic> mustacheContext = {
+      'units': <Map<String, dynamic>>[],
+      'links': migrationInfo.unitLinks(unitInfo),
+      'highlightJsPath': migrationInfo.highlightJsPath(unitInfo),
+      'highlightStylePath': migrationInfo.highlightStylePath(unitInfo),
+      'navContent': _computeNavigationContent(unitInfo),
+    };
+    mustacheContext['units'].add({
+      'path': unitInfo.path,
+      'regions': _computeRegions(unitInfo),
+    });
+    return _template.renderString(mustacheContext);
+  }
+
+  /// Return the content of the file with navigation links and anchors added.
+  String _computeNavigationContent(UnitInfo unitInfo) {
+    String content = unitInfo.content;
+    OffsetMapper mapper = unitInfo.offsetMapper;
+    List<NavigationRegion> regions = []
+      ..addAll(unitInfo.sources ?? <NavigationSource>[])
+      ..addAll(unitInfo.targets);
+    regions.sort((first, second) {
+      int offsetComparison = first.offset.compareTo(second.offset);
+      if (offsetComparison == 0) {
+        return first is NavigationSource ? -1 : 1;
+      }
+      return offsetComparison;
+    });
+
+    StringBuffer navContent = StringBuffer();
+    int previousOffset = 0;
+    for (int i = 0; i < regions.length; i++) {
+      NavigationRegion region = regions[i];
+      int offset = mapper.map(region.offset);
+      int length = region.length;
+      if (offset > previousOffset) {
+        // Write a non-target region.
+        navContent.write(content.substring(previousOffset, offset));
+        if (region is NavigationSource) {
+          if (i + 1 < regions.length &&
+              regions[i + 1].offset == region.offset) {
+            NavigationTarget target = region.target;
+            if (target == regions[i + 1]) {
+              // Add a target region. We skip the source because it links to
+              // itself, which is pointless.
+              navContent.write('<a id="o${region.offset}">');
+              navContent.write(content.substring(offset, offset + length));
+              navContent.write('</a>');
+            } else {
+              // Add a source and target region.
+              // TODO(brianwilkerson) Map the target's file path to the path of
+              //  the corresponding html file. I'd like to do this by adding a
+              //  `FilePathMapper` object so that it can't become inconsistent
+              //  with the code used to decide where to write the html.
+              String htmlPath = pathMapper.map(target.filePath);
+              navContent.write('<a id="o${region.offset}" ');
+              navContent.write('href="$htmlPath#o${target.offset}">');
+              navContent.write(content.substring(offset, offset + length));
+              navContent.write('</a>');
+            }
+            i++;
+          } else {
+            // Add a source region.
+            NavigationTarget target = region.target;
+            String htmlPath = pathMapper.map(target.filePath);
+            navContent.write('<a href="$htmlPath#o${target.offset}">');
+            navContent.write(content.substring(offset, offset + length));
+            navContent.write('</a>');
+          }
+        } else {
+          // Add a target region.
+          navContent.write('<a id="o${region.offset}">');
+          navContent.write(content.substring(offset, offset + length));
+          navContent.write('</a>');
+        }
+        previousOffset = offset + length;
+      }
+    }
+    if (previousOffset < content.length) {
+      // Last non-target region.
+      navContent.write(content.substring(previousOffset));
+    }
+    return navContent.toString();
+  }
+
+  /// Return a list of Mustache context, based on the [unitInfo] for both
+  /// unmodified and modified regions:
+  ///
+  /// * 'modified': Whether this region represents modified source, or
+  ///   unmodified.
+  /// * 'content': The textual content of this region.
+  /// * 'explanation': The Mustache context for the tooltip explaining why the
+  ///   content in this region was modified.
+  List<Map> _computeRegions(UnitInfo unitInfo) {
+    String content = unitInfo.content;
+    List<Map> regions = [];
+    int previousOffset = 0;
+    for (var region in unitInfo.regions) {
+      int offset = region.offset;
+      int length = region.length;
+      if (offset > previousOffset) {
+        // Display a region of unmodified content.
+        regions.add({
+          'modified': false,
+          'content': content.substring(previousOffset, offset),
+        });
+        previousOffset = offset + length;
+      }
+      List<Map> details = [];
+      for (var detail in region.details) {
+        details.add({
+          'description': detail.description,
+          'target': _uriForTarget(detail.target),
+        });
+      }
+      regions.add({
+        'modified': true,
+        'content': content.substring(offset, offset + length),
+        'explanation': region.explanation,
+        'details': details,
+      });
+    }
+    if (previousOffset < content.length) {
+      // Last region of unmodified content.
+      regions.add({
+        'modified': false,
+        'content': content.substring(previousOffset),
+      });
+    }
+    return regions;
+  }
+
+  /// Return the URL that will navigate to the given [target].
+  String _uriForTarget(NavigationTarget target) {
+    path.Context pathContext = migrationInfo.pathContext;
+    String targetPath = pathContext.setExtension(target.filePath, '.html');
+    String sourceDir = pathContext.dirname(unitInfo.path);
+    String relativePath = pathContext.relative(targetPath, from: sourceDir);
+    return '$relativePath#o${target.offset.toString()}';
+  }
+}
+
+/// A class storing rendering information for an entire migration report.
+///
+/// This generally provides one [InstrumentationRenderer] (for one library)
+/// with information about the rest of the libraries represented in the
+/// instrumentation output.
+class MigrationInfo {
+  /// The information about the compilation units that are are migrated.
+  final List<UnitInfo> units;
+
+  /// The resource provider's path context.
+  final path.Context pathContext;
+
+  /// The filesystem root used to create relative paths for each unit.
+  final String includedRoot;
+
+  MigrationInfo(this.units, this.pathContext, this.includedRoot);
+
+  /// The path to the highlight.js script, relative to [unitInfo].
+  String highlightJsPath(UnitInfo unitInfo) =>
+      pathContext.relative(pathContext.join(includedRoot, 'highlight.pack.js'),
+          from: pathContext.dirname(unitInfo.path));
+
+  /// The path to the highlight.js stylesheet, relative to [unitInfo].
+  String highlightStylePath(UnitInfo unitInfo) =>
+      pathContext.relative(pathContext.join(includedRoot, 'androidstudio.css'),
+          from: pathContext.dirname(unitInfo.path));
+
+  /// Generate mustache context for unit links, for navigation in the
+  /// instrumentation document for [thisUnit].
+  List<Map<String, Object>> unitLinks(UnitInfo thisUnit) {
+    return [
+      for (var unit in units)
+        {
+          'name': _computeName(unit),
+          'isLink': unit != thisUnit,
+          if (unit != thisUnit) 'href': _pathTo(target: unit, source: thisUnit)
+        }
+    ];
+  }
+
+  /// Return the path to [unit] from [includedRoot], to be used as a display
+  /// name for a library.
+  String _computeName(UnitInfo unit) =>
+      pathContext.relative(unit.path, from: includedRoot);
+
+  /// The path to [target], relative to [from].
+  String _pathTo({@required UnitInfo target, @required UnitInfo source}) {
+    String targetPath = pathContext.setExtension(target.path, '.html');
+    String sourceDir = pathContext.dirname(source.path);
+    return pathContext.relative(targetPath, from: sourceDir);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
index 7a66011..57f6002 100644
--- a/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/migration_info.dart
@@ -15,19 +15,35 @@
   LibraryInfo(this.units);
 }
 
+/// A location from or to which a user might want to navigate.
+abstract class NavigationRegion {
+  /// The offset of the region.
+  final int offset;
+
+  /// The length of the region.
+  final int length;
+
+  /// Initialize a newly created link.
+  NavigationRegion(this.offset, this.length);
+}
+
+/// A location from which a user might want to navigate.
+class NavigationSource extends NavigationRegion {
+  /// The target to which the user should be navigated.
+  final NavigationTarget target;
+
+  /// Initialize a newly created link.
+  NavigationSource(int offset, int length, this.target) : super(offset, length);
+}
+
 /// A location to which a user might want to navigate.
-class NavigationTarget {
+class NavigationTarget extends NavigationRegion {
   /// The file containing the anchor.
   final String filePath;
 
-  /// The offset of the anchor.
-  final int offset;
-
-  /// The length of the anchor.
-  final int length;
-
   /// Initialize a newly created anchor.
-  NavigationTarget(this.filePath, this.offset, this.length);
+  NavigationTarget(this.filePath, int offset, int length)
+      : super(offset, length);
 
   @override
   int get hashCode => JenkinsSmiHash.hash3(filePath.hashCode, offset, length);
@@ -85,6 +101,10 @@
   /// them. The offsets in these regions are offsets into the post-edit content.
   final List<RegionInfo> regions = [];
 
+  /// The navigation sources that are located in this file. The offsets in these
+  /// sources are offsets into the pre-edit content.
+  List<NavigationSource> sources;
+
   /// The navigation targets that are located in this file. The offsets in these
   /// targets are offsets into the pre-edit content.
   final Set<NavigationTarget> targets = {};
diff --git a/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart b/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart
new file mode 100644
index 0000000..f6939c0
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/nnbd_migration/path_mapper.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2019, 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:analyzer/file_system/file_system.dart';
+import 'package:path/path.dart' as path;
+
+/// An object that can map the file paths of analyzed files to the file paths of
+/// the HTML files used to view the content of those files.
+class PathMapper {
+  /// The resource provider used to map paths.
+  ResourceProvider provider;
+
+  /// The absolute path of the folder that should contain all of the generated
+  /// HTML files.
+  final String outputFolder;
+
+  /// The root of the package containing the files being migrated.
+  final String packageRoot;
+
+  /// A table mapping the file paths of analyzed files to the file paths of the
+  /// HTML files used to view the content of those files.
+  final Map<String, String> pathMap = {};
+
+  /// The index to be used when creating the next synthetic file name.
+  int nextIndex = 1;
+
+  /// Initialize a newly created path mapper.
+  PathMapper(this.provider, this.outputFolder, this.packageRoot);
+
+  /// Return the path of the HTML file used to view the content of the analyzed
+  /// file with the given [path].
+  String map(String path) {
+    return pathMap.putIfAbsent(path, () => _computePathFor(path));
+  }
+
+  /// Return the path of the HTML file corresponding to the Dart file with the
+  /// given [path].
+  String _computePathFor(String filePath) {
+    path.Context context = provider.pathContext;
+    if (context.isWithin(packageRoot, filePath)) {
+      String packageParent = context.dirname(packageRoot);
+      String relative = context.relative(filePath, from: packageParent);
+      return context.join(
+          outputFolder, context.setExtension(relative, '.html'));
+    }
+    // TODO(brianwilkerson) Find a better mapping algorithm, that would produce
+    //  a more readable URI. For example, have other packages and the sdk be
+    //  parallel to the directory containing the files for the library being
+    //  migrated.
+    return context.join(outputFolder, 'f${nextIndex++}.html');
+  }
+}
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
index 3b1d28a..995aa40 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_initialize.dart
@@ -58,6 +58,10 @@
     final renameOptionsSupport =
         params.capabilities.textDocument?.rename?.prepareSupport ?? false;
 
+    final dynamicTextSyncRegistration = params
+            .capabilities.textDocument?.synchronization?.dynamicRegistration ??
+        false;
+
     // When adding new capabilities to the server that may apply to specific file
     // types, it's important to update
     // [IntializedMessageHandler._performDynamicRegistration()] to notify
@@ -66,8 +70,13 @@
     // requests where we have only partial support for some types).
     server.capabilities = new ServerCapabilities(
         Either2<TextDocumentSyncOptions, num>.t1(new TextDocumentSyncOptions(
-          true,
-          TextDocumentSyncKind.Incremental,
+          // The open/close and sync kind flags are registered dynamically if the
+          // client supports them, so these static registrations are based on whether
+          // the client supports dynamic registration.
+          dynamicTextSyncRegistration ? false : true,
+          dynamicTextSyncRegistration
+              ? TextDocumentSyncKind.None
+              : TextDocumentSyncKind.Incremental,
           false,
           false,
           null,
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index 6c51810..efbaa0c 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -134,9 +134,7 @@
   static const FLUTTER_MOVE_UP =
       const AssistKind('dart.assist.flutter.move.up', 30, "Move widget up");
   static const FLUTTER_REMOVE_WIDGET = const AssistKind(
-      'dart.assist.flutter.removeWidget',
-      30,
-      "Replace widget with its children");
+      'dart.assist.flutter.removeWidget', 30, "Remove this widget");
   static const FLUTTER_SWAP_WITH_CHILD = const AssistKind(
       'dart.assist.flutter.swap.withChild', 30, "Swap with child");
   static const FLUTTER_SWAP_WITH_PARENT = const AssistKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/base_processor.dart b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
index 32e627e..3c3870b 100644
--- a/pkg/analysis_server/lib/src/services/correction/base_processor.dart
+++ b/pkg/analysis_server/lib/src/services/correction/base_processor.dart
@@ -65,6 +65,109 @@
       (session.analysisContext.analysisOptions as AnalysisOptionsImpl)
           .experimentStatus;
 
+  Future<ChangeBuilder> createBuilder_addDiagnosticPropertyReference() async {
+    final node = this.node;
+    if (node is! SimpleIdentifier) {
+      _coverageMarker();
+      return null;
+    }
+    SimpleIdentifier name = node;
+    final parent = node.parent;
+
+    DartType type;
+
+    // Getter.
+    if (parent is MethodDeclaration) {
+      MethodDeclaration methodDeclaration = parent;
+      var element = methodDeclaration.declaredElement;
+      if (element is PropertyAccessorElement) {
+        PropertyAccessorElement propertyAccessor = element;
+        type = propertyAccessor.returnType;
+      }
+      // Field.
+    } else if (parent is VariableDeclaration) {
+      VariableDeclaration variableDeclaration = parent;
+      final element = variableDeclaration.declaredElement;
+      if (element is FieldElement) {
+        FieldElement fieldElement = element;
+        type = fieldElement.type;
+      }
+    }
+
+    if (type == null) {
+      return null;
+    }
+
+    var constructorInvocation;
+    if (type.isDartCoreBool) {
+      constructorInvocation = 'DiagnosticsProperty<bool>';
+    } else if (type.isDartCoreInt) {
+      constructorInvocation = 'IntProperty';
+    } else if (type.isDartCoreDouble) {
+      constructorInvocation = 'DoubleProperty';
+    } else if (type.isDartCoreString) {
+      constructorInvocation = 'StringProperty';
+    } else if (isEnum(type)) {
+      constructorInvocation = 'EnumProperty';
+    }
+
+    // todo (pq): migrate type string generation to within change and use DartEditBuilder.writeType
+
+    if (constructorInvocation == null) {
+      return null;
+    }
+
+    ClassDeclaration classDeclaration =
+        parent.thisOrAncestorOfType<ClassDeclaration>();
+    final debugFillProperties =
+        classDeclaration.getMethod('debugFillProperties');
+    if (debugFillProperties != null) {
+      final body = debugFillProperties.body;
+      if (body is BlockFunctionBody) {
+        BlockFunctionBody functionBody = body;
+
+        var offset;
+        var prefix;
+        if (functionBody.block.statements.isEmpty) {
+          offset = functionBody.block.leftBracket.offset;
+          prefix = utils.getLinePrefix(offset) + utils.getIndent(1);
+        } else {
+          offset = functionBody.block.statements.last.endToken.offset;
+          prefix = utils.getLinePrefix(offset);
+        }
+
+        var parameters = debugFillProperties.parameters.parameters;
+        var propertiesBuilderName;
+        for (var parameter in parameters) {
+          if (parameter is SimpleFormalParameter) {
+            final type = parameter.type;
+            if (type is TypeName) {
+              if (type.name.name == 'DiagnosticPropertiesBuilder') {
+                propertiesBuilderName = parameter.identifier.name;
+                break;
+              }
+            }
+          }
+        }
+        if (propertiesBuilderName == null) {
+          return null;
+        }
+
+        final changeBuilder = _newDartChangeBuilder();
+        await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+          builder.addInsertion(utils.getLineNext(offset),
+              (DartEditBuilder builder) {
+            builder.write(
+                "$prefix$propertiesBuilderName.add($constructorInvocation('${name.name}', ${name.name}));$eol");
+          });
+        });
+        return changeBuilder;
+      }
+    }
+
+    return null;
+  }
+
   Future<ChangeBuilder>
       createBuilder_addTypeAnnotation_DeclaredIdentifier() async {
     DeclaredIdentifier declaredIdentifier =
@@ -860,46 +963,6 @@
     return changeBuilder;
   }
 
-  Future<ChangeBuilder> createBuilder_sortChildPropertyLast() async {
-    NamedExpression childProp = flutter.findNamedExpression(node, 'child');
-    if (childProp == null) {
-      childProp = flutter.findNamedExpression(node, 'children');
-    }
-    if (childProp == null) {
-      return null;
-    }
-
-    var parent = childProp.parent?.parent;
-    if (parent is! InstanceCreationExpression ||
-        !flutter.isWidgetCreation(parent)) {
-      return null;
-    }
-
-    InstanceCreationExpression creationExpression = parent;
-    var args = creationExpression.argumentList;
-
-    var last = args.arguments.last;
-    if (last == childProp) {
-      // Already sorted.
-      return null;
-    }
-
-    var changeBuilder = _newDartChangeBuilder();
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      var start = childProp.beginToken.previous.end;
-      var end = childProp.endToken.next.end;
-      var childRange = range.startOffsetEndOffset(start, end);
-
-      var childText = utils.getRangeText(childRange);
-      builder.addSimpleReplacement(childRange, '');
-      builder.addSimpleInsertion(last.end + 1, childText);
-
-      changeBuilder.setSelection(new Position(file, last.end + 1));
-    });
-
-    return changeBuilder;
-  }
-
   /// todo (pq): unify with similar behavior in fix.
   Future<ChangeBuilder> createBuilder_removeTypeAnnotation() async {
     VariableDeclarationList declarationList =
@@ -945,6 +1008,46 @@
     return changeBuilder;
   }
 
+  Future<ChangeBuilder> createBuilder_sortChildPropertyLast() async {
+    NamedExpression childProp = flutter.findNamedExpression(node, 'child');
+    if (childProp == null) {
+      childProp = flutter.findNamedExpression(node, 'children');
+    }
+    if (childProp == null) {
+      return null;
+    }
+
+    var parent = childProp.parent?.parent;
+    if (parent is! InstanceCreationExpression ||
+        !flutter.isWidgetCreation(parent)) {
+      return null;
+    }
+
+    InstanceCreationExpression creationExpression = parent;
+    var args = creationExpression.argumentList;
+
+    var last = args.arguments.last;
+    if (last == childProp) {
+      // Already sorted.
+      return null;
+    }
+
+    var changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      var start = childProp.beginToken.previous.end;
+      var end = childProp.endToken.next.end;
+      var childRange = range.startOffsetEndOffset(start, end);
+
+      var childText = utils.getRangeText(childRange);
+      builder.addSimpleReplacement(childRange, '');
+      builder.addSimpleInsertion(last.end + 1, childText);
+
+      changeBuilder.setSelection(new Position(file, last.end + 1));
+    });
+
+    return changeBuilder;
+  }
+
   @protected
   Future<ChangeBuilder> createBuilder_useCurlyBraces() async {
     Future<ChangeBuilder> doStatement(DoStatement node) async {
@@ -1105,6 +1208,11 @@
     return null;
   }
 
+  bool isEnum(DartType type) {
+    final element = type.element;
+    return element is ClassElement && element.isEnum;
+  }
+
   @protected
   bool setupCompute() {
     final locator = NodeLocator(selectionOffset, selectionEnd);
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index b2bc9a3..6a005f2 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -142,6 +142,10 @@
       const FixKind('ADD_CONST', 50, "Add 'const' modifier");
   static const ADD_CURLY_BRACES =
       const FixKind('ADD_CURLY_BRACES', 50, "Add curly braces");
+  static const ADD_DIAGNOSTIC_PROPERTY_REFERENCE = const FixKind(
+      'ADD_DIAGNOSTIC_PROPERTY_REFERENCE',
+      50,
+      "Add a debug reference to this property");
   static const ADD_FIELD_FORMAL_PARAMETERS = const FixKind(
       'ADD_FIELD_FORMAL_PARAMETERS', 70, "Add final field formal parameters");
   static const ADD_MISSING_ENUM_CASE_CLAUSES = const FixKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index 7dff396..801408f 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -628,6 +628,9 @@
       if (name == LintNames.curly_braces_in_flow_control_structures) {
         await _addFix_addCurlyBraces();
       }
+      if (name == LintNames.diagnostic_describe_all_properties) {
+        await _addFix_addDiagnosticPropertyReference();
+      }
       if (name == LintNames.empty_catches) {
         await _addFix_removeEmptyCatch();
       }
@@ -781,6 +784,12 @@
     _addFixFromBuilder(changeBuilder, DartFixKind.ADD_CURLY_BRACES);
   }
 
+  Future<void> _addFix_addDiagnosticPropertyReference() async {
+    final changeBuilder = await createBuilder_addDiagnosticPropertyReference();
+    _addFixFromBuilder(
+        changeBuilder, DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE);
+  }
+
   Future<void> _addFix_addExplicitCast() async {
     if (coveredNode is! Expression) {
       return;
@@ -3525,6 +3534,47 @@
     }
   }
 
+  Future<void> _addFix_removeUnusedElement() async {
+    final sourceRanges = <SourceRange>[];
+    final referencedNode = node.parent;
+    if (referencedNode is ClassDeclaration ||
+        referencedNode is EnumDeclaration ||
+        referencedNode is FunctionDeclaration ||
+        referencedNode is FunctionTypeAlias ||
+        referencedNode is MethodDeclaration ||
+        referencedNode is VariableDeclaration) {
+      final element = referencedNode is Declaration
+          ? referencedNode.declaredElement
+          : (referencedNode as NamedCompilationUnitMember).declaredElement;
+      final references = _findAllReferences(unit, element);
+      // todo (pq): consider filtering for references that are limited to within the class.
+      if (references.length == 1) {
+        var sourceRange;
+        if (referencedNode is VariableDeclaration) {
+          VariableDeclarationList parent = referencedNode.parent;
+          if (parent.variables.length == 1) {
+            sourceRange = utils.getLinesRange(range.node(parent.parent));
+          } else {
+            sourceRange = range.nodeInList(parent.variables, node);
+          }
+        } else {
+          sourceRange = utils.getLinesRange(range.node(referencedNode));
+        }
+        sourceRanges.add(sourceRange);
+      }
+    }
+
+    if (sourceRanges.isNotEmpty) {
+      final changeBuilder = _newDartChangeBuilder();
+      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+        for (var sourceRange in sourceRanges) {
+          builder.addDeletion(sourceRange);
+        }
+      });
+      _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_ELEMENT);
+    }
+  }
+
   Future<void> _addFix_removeUnusedField() async {
     final declaration = node.parent;
     if (declaration is! VariableDeclaration) {
@@ -3588,47 +3638,6 @@
     _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_FIELD);
   }
 
-  Future<void> _addFix_removeUnusedElement() async {
-    final sourceRanges = <SourceRange>[];
-    final referencedNode = node.parent;
-    if (referencedNode is ClassDeclaration ||
-        referencedNode is EnumDeclaration ||
-        referencedNode is FunctionDeclaration ||
-        referencedNode is FunctionTypeAlias ||
-        referencedNode is MethodDeclaration ||
-        referencedNode is VariableDeclaration) {
-      final element = referencedNode is Declaration
-          ? referencedNode.declaredElement
-          : (referencedNode as NamedCompilationUnitMember).declaredElement;
-      final references = _findAllReferences(unit, element);
-      // todo (pq): consider filtering for references that are limited to within the class.
-      if (references.length == 1) {
-        var sourceRange;
-        if (referencedNode is VariableDeclaration) {
-          VariableDeclarationList parent = referencedNode.parent;
-          if (parent.variables.length == 1) {
-            sourceRange = utils.getLinesRange(range.node(parent.parent));
-          } else {
-            sourceRange = range.nodeInList(parent.variables, node);
-          }
-        } else {
-          sourceRange = utils.getLinesRange(range.node(referencedNode));
-        }
-        sourceRanges.add(sourceRange);
-      }
-    }
-
-    if (sourceRanges.isNotEmpty) {
-      final changeBuilder = _newDartChangeBuilder();
-      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-        for (var sourceRange in sourceRanges) {
-          builder.addDeletion(sourceRange);
-        }
-      });
-      _addFixFromBuilder(changeBuilder, DartFixKind.REMOVE_UNUSED_ELEMENT);
-    }
-  }
-
   Future<void> _addFix_removeUnusedImport() async {
     // prepare ImportDirective
     ImportDirective importDirective =
diff --git a/pkg/analysis_server/lib/src/services/linter/lint_names.dart b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
index b3ee6f1..fbd3a46 100644
--- a/pkg/analysis_server/lib/src/services/linter/lint_names.dart
+++ b/pkg/analysis_server/lib/src/services/linter/lint_names.dart
@@ -20,6 +20,8 @@
   static const String await_only_futures = 'await_only_futures';
   static const String curly_braces_in_flow_control_structures =
       'curly_braces_in_flow_control_structures';
+  static const String diagnostic_describe_all_properties =
+      'diagnostic_describe_all_properties';
   static const String empty_catches = 'empty_catches';
   static const String empty_constructor_bodies = 'empty_constructor_bodies';
   static const String empty_statements = 'empty_statements';
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
index 3feab8b..ba6c8a3 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_widget.dart
@@ -381,7 +381,7 @@
     for (var invocation in collector.invocations) {
       List<Expression> arguments = invocation.argumentList.arguments;
       builder.addReplacement(range.node(invocation), (builder) {
-        builder.write('new $name(');
+        builder.write('$name(');
 
         // Insert field references (as named arguments).
         // Ensure that invocation arguments are named.
@@ -545,7 +545,7 @@
 
   /// Write instantiation of the new widget class.
   void _writeWidgetInstantiation(DartEditBuilder builder) {
-    builder.write('new $name(');
+    builder.write('$name(');
 
     for (var parameter in _parameters) {
       if (parameter != _parameters.first) {
diff --git a/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart b/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
index 7865f34..7056d15 100644
--- a/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
+++ b/pkg/analysis_server/test/edit/nnbd_migration/instrumentation_output_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:analysis_server/src/edit/nnbd_migration/instrumentation_renderer.dart';
 import 'package:analysis_server/src/edit/nnbd_migration/migration_info.dart';
+import 'package:analysis_server/src/edit/nnbd_migration/path_mapper.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -21,61 +22,73 @@
   /// library.
   // TODO(srawlins): Add tests for navigation links, which use multiple
   // libraries.
-  String renderLibrary(LibraryInfo libraryInfo) {
-    MigrationInfo migrationInfo =
-        MigrationInfo([libraryInfo], resourceProvider.pathContext, '/project');
-    return InstrumentationRenderer(libraryInfo, migrationInfo).render();
+  List<String> renderLibrary(LibraryInfo libraryInfo) {
+    String packageRoot = resourceProvider.convertPath('/package');
+    String outputDir = resourceProvider.convertPath('/output');
+    MigrationInfo migrationInfo = MigrationInfo(
+        libraryInfo.units, resourceProvider.pathContext, packageRoot);
+    List<String> contents = [];
+    for (UnitInfo unitInfo in libraryInfo.units) {
+      contents.add(InstrumentationRenderer(unitInfo, migrationInfo,
+              PathMapper(resourceProvider, outputDir, packageRoot))
+          .render());
+    }
+    return contents;
   }
 
   test_outputContainsEachPath() async {
     LibraryInfo info = LibraryInfo([
-      unit('/lib/a.dart', 'int? a = null;',
+      unit('/package/lib/a.dart', 'int? a = null;',
           regions: [RegionInfo(3, 1, 'null was assigned', [])]),
-      unit('/lib/part1.dart', 'int? b = null;',
+      unit('/package/lib/part1.dart', 'int? b = null;',
           regions: [RegionInfo(3, 1, 'null was assigned', [])]),
-      unit('/lib/part2.dart', 'int? c = null;',
+      unit('/package/lib/part2.dart', 'int? c = null;',
           regions: [RegionInfo(3, 1, 'null was assigned', [])]),
     ]);
-    String output = renderLibrary(info);
-    expect(output, contains('<h2>/lib/a.dart</h2>'));
-    expect(output, contains('<h2>/lib/part1.dart</h2>'));
-    expect(output, contains('<h2>/lib/part2.dart</h2>'));
+    List<String> contents = renderLibrary(info);
+    expect(contents[0], contains(resourceProvider.convertPath('lib/a.dart')));
+    expect(
+        contents[1], contains(resourceProvider.convertPath('lib/part1.dart')));
+    expect(
+        contents[2], contains(resourceProvider.convertPath('lib/part2.dart')));
   }
 
   test_outputContainsEscapedHtml() async {
     LibraryInfo info = LibraryInfo([
-      unit('/lib/a.dart', 'List<String>? a = null;',
+      unit('/package/lib/a.dart', 'List<String>? a = null;',
           regions: [RegionInfo(12, 1, 'null was assigned', [])]),
     ]);
-    String output = renderLibrary(info);
+    String output = renderLibrary(info)[0];
     expect(
         output,
         contains('List&lt;String&gt;<span class="region">?'
-            '<span class="tooltip">null was assigned</span></span> a = null;'));
+            '<span class="tooltip">null was assigned<ul></ul></span></span> '
+            'a = null;'));
   }
 
   test_outputContainsEscapedHtml_ampersand() async {
     LibraryInfo info = LibraryInfo([
-      unit('/lib/a.dart', 'bool a = true && false;', regions: []),
+      unit('/package/lib/a.dart', 'bool a = true && false;', regions: []),
     ]);
-    String output = renderLibrary(info);
+    String output = renderLibrary(info)[0];
     expect(output, contains('bool a = true &amp;&amp; false;'));
   }
 
   test_outputContainsModifiedAndUnmodifiedRegions() async {
     LibraryInfo info = LibraryInfo([
-      unit('/lib/a.dart', 'int? a = null;',
+      unit('/package/lib/a.dart', 'int? a = null;',
           regions: [RegionInfo(3, 1, 'null was assigned', [])]),
     ]);
-    String output = renderLibrary(info);
+    String output = renderLibrary(info)[0];
     expect(
         output,
         contains('int<span class="region">?'
-            '<span class="tooltip">null was assigned</span></span> a = null;'));
+            '<span class="tooltip">null was assigned<ul></ul></span></span> '
+            'a = null;'));
   }
 
   UnitInfo unit(String path, String content, {List<RegionInfo> regions}) {
-    return UnitInfo(path)
+    return UnitInfo(resourceProvider.convertPath(path))
       ..content = content
       ..regions.addAll(regions);
   }
diff --git a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
index 40e2ff6..799c69e 100644
--- a/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/diagnostic_test.dart
@@ -15,6 +15,9 @@
 
 @reflectiveTest
 class DiagnosticTest extends AbstractLspAnalysisServerIntegrationTest {
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_initialAnalysis() async {
     newFile(mainFilePath, content: 'String a = 1;');
 
@@ -30,6 +33,9 @@
     expect(diagnostic.range.end.character, equals(12));
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_lints() async {
     newFile(mainFilePath, content: '''main() async => await 1;''');
     newFile(analysisOptionsPath, content: '''
diff --git a/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart b/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
index 8d364dc..91f75bc 100644
--- a/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/initialization_test.dart
@@ -17,6 +17,9 @@
 
 @reflectiveTest
 class InitializationTest extends AbstractLspAnalysisServerIntegrationTest {
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_initialize_invalidParams() async {
     final params = {'processId': 'invalid'};
     final request = new RequestMessage(
diff --git a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
index e1eeec2..23317b4 100644
--- a/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/integration_tests.dart
@@ -144,11 +144,24 @@
 
     String dartBinary = Platform.executable;
 
-    // TODO(dantup): The other servers integration tests can run with a snapshot
-    // which is much faster - we may wish to investigate doing the same here.
-    final rootDir =
-        findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
-    final serverPath = normalize(join(rootDir, 'bin', 'server.dart'));
+    final bool useSnapshot = true;
+    String serverPath;
+
+    if (useSnapshot) {
+      // Look for snapshots/analysis_server.dart.snapshot.
+      serverPath = normalize(join(dirname(Platform.resolvedExecutable),
+          'snapshots', 'analysis_server.dart.snapshot'));
+
+      if (!FileSystemEntity.isFileSync(serverPath)) {
+        // Look for dart-sdk/bin/snapshots/analysis_server.dart.snapshot.
+        serverPath = normalize(join(dirname(Platform.resolvedExecutable),
+            'dart-sdk', 'bin', 'snapshots', 'analysis_server.dart.snapshot'));
+      }
+    } else {
+      final rootDir =
+          findRoot(Platform.script.toFilePath(windows: Platform.isWindows));
+      serverPath = normalize(join(rootDir, 'bin', 'server.dart'));
+    }
 
     final arguments = [serverPath, '--lsp', '--suppress-analytics'];
     _process = await Process.start(dartBinary, arguments);
diff --git a/pkg/analysis_server/test/integration/lsp_server/server_test.dart b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
index 0b73ad4..fd7e279 100644
--- a/pkg/analysis_server/test/integration/lsp_server/server_test.dart
+++ b/pkg/analysis_server/test/integration/lsp_server/server_test.dart
@@ -18,6 +18,9 @@
 
 @reflectiveTest
 class ServerTest extends AbstractLspAnalysisServerIntegrationTest {
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_diagnosticServer() async {
     await initialize();
 
@@ -38,6 +41,9 @@
     expect(responseBody, contains('<title>Analysis Server</title>'));
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_exit_inintializedWithShutdown() async {
     await initialize();
     await sendShutdown();
@@ -53,6 +59,9 @@
     expect(exitCode, equals(0));
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_exit_initializedWithoutShutdown() async {
     // Send a request that we can wait for, to ensure the server is fully ready
     // before we send exit. Otherwise the exit notification won't be handled for
@@ -70,6 +79,9 @@
     expect(exitCode, equals(1));
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_exit_uninintializedWithShutdown() async {
     await sendShutdown();
     sendExit();
@@ -84,6 +96,9 @@
     expect(exitCode, equals(0));
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_exit_uninitializedWithoutShutdown() async {
     // This tests the same as test_exit_withoutShutdown but without sending
     // initialize. It can't be as strict with the timeout as the server may take
diff --git a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
index 55d5140..6a1cd63 100644
--- a/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_refactor_test.dart
@@ -112,7 +112,7 @@
   Widget build(BuildContext context) {
     return new Row(
       children: <Widget>[
-        new NewWidget(),
+        NewWidget(),
         new Text('CCC'),
         new Text('DDD'),
       ],
diff --git a/pkg/analysis_server/test/lsp/initialization_test.dart b/pkg/analysis_server/test/lsp/initialization_test.dart
index 648b7ed..7de98f7 100644
--- a/pkg/analysis_server/test/lsp/initialization_test.dart
+++ b/pkg/analysis_server/test/lsp/initialization_test.dart
@@ -208,9 +208,23 @@
     });
 
     // Initialize with no dynamic registrations advertised.
-    await initialize();
+    final initResponse = await initialize();
     await pumpEventQueue();
 
+    // When dynamic registration is not supported, we will always statically
+    // request text document open/close and incremental updates.
+    InitializeResult initResult = initResponse.result;
+    expect(initResult.capabilities, isNotNull);
+    expect(initResult.capabilities.textDocumentSync, isNotNull);
+    initResult.capabilities.textDocumentSync.map(
+      (options) {
+        expect(options.openClose, isTrue);
+        expect(options.change, equals(TextDocumentSyncKind.Incremental));
+      },
+      (_) =>
+          throw 'Expected textDocumentSync capabilities to be a $TextDocumentSyncOptions',
+    );
+
     expect(didGetRegisterCapabilityRequest, isFalse);
   }
 
@@ -237,7 +251,8 @@
     // for ex including analysis_options.yaml in text synchronization but not
     // for hovers.
     List<Registration> registrations;
-    await handleExpectedRequest<void, RegistrationParams, void>(
+    final initResponse =
+        await handleExpectedRequest<ResponseMessage, RegistrationParams, void>(
       Method.client_registerCapability,
       () => initialize(
           // Support dynamic registration for both text sync + hovers.
@@ -248,6 +263,21 @@
           registrations = registrationParams.registrations,
     );
 
+    // Because we support dynamic registration for synchronisation, we won't send
+    // static registrations for them.
+    // https://github.com/dart-lang/sdk/issues/38490
+    InitializeResult initResult = initResponse.result;
+    expect(initResult.capabilities, isNotNull);
+    expect(initResult.capabilities.textDocumentSync, isNotNull);
+    initResult.capabilities.textDocumentSync.map(
+      (options) {
+        expect(options.openClose, isFalse);
+        expect(options.change, equals(TextDocumentSyncKind.None));
+      },
+      (_) =>
+          throw 'Expected textDocumentSync capabilities to be a $TextDocumentSyncOptions',
+    );
+
     // Should container Hover, DidOpen, DidClose, DidChange.
     expect(registrations, hasLength(4));
     final hover =
diff --git a/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart b/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
index 580a076..1ed98d3 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_widget_test.dart
@@ -121,7 +121,7 @@
   Widget build(BuildContext context) {
     return new Row(
       children: <Widget>[
-        new Test(),
+        Test(),
         new Text('CCC'),
         new Text('DDD'),
       ],
@@ -173,7 +173,7 @@
   Widget foo() {
     return new Row(
       children: <Widget>[
-        new Test(),
+        Test(),
         new Text('BBB'),
       ],
     );
@@ -214,7 +214,7 @@
 class MyWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
-    return new Test();
+    return Test();
   }
 }
 
@@ -249,7 +249,7 @@
 import 'package:flutter/material.dart';
 
 Widget main() {
-  return new Test();
+  return Test();
 }
 
 class Test extends StatelessWidget {
@@ -301,7 +301,7 @@
 Widget main() {
   return new Row(
     children: <Widget>[
-      new Test(),
+      Test(),
       new Text('BBB'),
     ],
   );
@@ -409,7 +409,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(c: c);
+    return Test(c: c);
   }
 }
 
@@ -462,7 +462,7 @@
 class MyWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
-    return new Test();
+    return Test();
   }
 }
 
@@ -524,8 +524,8 @@
     int bar = 1;
     return new Row(
       children: <Widget>[
-        new Test(foo: foo, p1: 'aaa', p2: bar),
-        new Test(foo: foo, p1: 'bbb', p2: 2),
+        Test(foo: foo, p1: 'aaa', p2: bar),
+        Test(foo: foo, p1: 'bbb', p2: 2),
       ],
     );
   }
@@ -596,8 +596,8 @@
     int bar = 1;
     return new Row(
       children: <Widget>[
-        new Test(foo: foo, p1: 'aaa', p2: bar),
-        new Test(foo: foo, p1: 'bbb', p2: 2),
+        Test(foo: foo, p1: 'aaa', p2: bar),
+        Test(foo: foo, p1: 'bbb', p2: 2),
       ],
     );
   }
@@ -651,7 +651,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(field: field);
+    return Test(field: field);
   }
 }
 
@@ -703,7 +703,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(c: c);
+    return Test(c: c);
   }
 }
 
@@ -747,7 +747,7 @@
 class MyWidget extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
-    return new Test();
+    return Test();
   }
 }
 
@@ -853,7 +853,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(c: c);
+    return Test(c: c);
   }
 }
 
@@ -919,7 +919,7 @@
   @override
   Widget build(BuildContext context) {
     String local;
-    return new Test(local: local);
+    return Test(local: local);
   }
 }
 
@@ -987,7 +987,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(field: _field);
+    return Test(field: _field);
   }
 }
 
@@ -1033,7 +1033,7 @@
 
   @override
   Widget build(BuildContext context) {
-    return new Test(field: field, field2: _field);
+    return Test(field: field, field2: _field);
   }
 }
 
@@ -1086,7 +1086,7 @@
   @override
   Widget build(BuildContext context) {
     String local;
-    return new Test(field: field, local: local);
+    return Test(field: field, local: local);
   }
 }
 
@@ -1157,7 +1157,7 @@
   var index = 0;
   var a = 'a $index';
 // start
-  return new Test(index: index, a: a);
+  return Test(index: index, a: a);
 // end
 }
 
diff --git a/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart b/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
index 408a7a7..a2b0dcc 100644
--- a/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
+++ b/pkg/analysis_server/test/src/edit/fix/non_nullable_fix_test.dart
@@ -136,11 +136,11 @@
     Folder outputDir = getFolder('/outputDir');
     await performFix(included: [projectPath], outputDir: outputDir.path);
     expect(outputDir.exists, true);
-    expect(getFile('/outputDir/bin/bin.html').exists, isTrue);
-    expect(getFile('/outputDir/lib/lib1.html').exists, isTrue);
-    expect(getFile('/outputDir/lib/lib2.html').exists, isTrue);
-    expect(getFile('/outputDir/lib/src/lib3.html').exists, isTrue);
-    expect(getFile('/outputDir/test/test.html').exists, isTrue);
+    expect(getFile('/outputDir/project/bin/bin.html').exists, isTrue);
+    expect(getFile('/outputDir/project/lib/lib1.html').exists, isTrue);
+    expect(getFile('/outputDir/project/lib/lib2.html').exists, isTrue);
+    expect(getFile('/outputDir/project/lib/src/lib3.html').exists, isTrue);
+    expect(getFile('/outputDir/project/test/test.html').exists, isTrue);
   }
 
   test_outputDirContainsFilesRootedInASubdirectory() async {
@@ -150,9 +150,9 @@
         included: [context.join(projectPath, 'lib')],
         outputDir: outputDir.path);
     expect(outputDir.exists, true);
-    expect(getFile('/outputDir/lib1.html').exists, isTrue);
-    expect(getFile('/outputDir/lib2.html').exists, isTrue);
-    expect(getFile('/outputDir/src/lib3.html').exists, isTrue);
+    expect(getFile('/outputDir/lib/lib1.html').exists, isTrue);
+    expect(getFile('/outputDir/lib/lib2.html').exists, isTrue);
+    expect(getFile('/outputDir/lib/src/lib3.html').exists, isTrue);
   }
 
   test_outputDirContainsFilesRootedInParentOfSingleFile() async {
@@ -162,6 +162,11 @@
         included: [context.join(projectPath, 'lib', 'lib2.dart')],
         outputDir: outputDir.path);
     expect(outputDir.exists, true);
-    expect(outputDir.getChildAssumingFile('lib2.html').exists, isTrue);
+    expect(
+        outputDir
+            .getChildAssumingFolder('lib')
+            .getChildAssumingFile('lib2.html')
+            .exists,
+        isTrue);
   }
 }
diff --git a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
index ca0162f..d349e0d 100644
--- a/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
+++ b/pkg/analysis_server/test/src/edit/nnbd_migration/info_builder_test.dart
@@ -25,7 +25,7 @@
 class InfoBuilderTest extends AbstractAnalysisTest {
   /// The information produced by the InfoBuilder, or `null` if [buildInfo] has
   /// not yet completed.
-  List<LibraryInfo> infos;
+  List<UnitInfo> infos;
 
   /// Use the InfoBuilder to build information. The information will be stored
   /// in [infos].
@@ -53,7 +53,7 @@
     infos = await builder.explainMigration();
   }
 
-  test_parameter_nullableFromInvocation() async {
+  test_parameter_nullable_fromInvocation() async {
     addTestFile('''
 void f(String s) {}
 void g() {
@@ -62,9 +62,7 @@
 ''');
     await buildInfo();
     expect(infos, hasLength(1));
-    List<UnitInfo> units = infos[0].units;
-    expect(units, hasLength(1));
-    UnitInfo unit = units[0];
+    UnitInfo unit = infos[0];
     expect(unit.path, testFile);
     expect(unit.content, '''
 void f(String? s) {}
@@ -77,5 +75,37 @@
     RegionInfo region = regions[0];
     expect(region.offset, 13);
     expect(region.length, 1);
+    List<RegionDetail> details = region.details;
+    expect(details, hasLength(1));
+  }
+
+  test_parameter_nullable_fromOverriden() async {
+    addTestFile('''
+class A {
+  void m(p) {}
+}
+class B extends A {
+  void m(Object p) {}
+}
+''');
+    await buildInfo();
+    expect(infos, hasLength(1));
+    UnitInfo unit = infos[0];
+    expect(unit.path, testFile);
+    expect(unit.content, '''
+class A {
+  void m(p) {}
+}
+class B extends A {
+  void m(Object? p) {}
+}
+''');
+    List<RegionInfo> regions = unit.regions;
+    expect(regions, hasLength(1));
+    RegionInfo region = regions[0];
+    expect(region.offset, 62);
+    expect(region.length, 1);
+    List<RegionDetail> details = region.details;
+    expect(details, hasLength(1));
   }
 }
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index df7d05f..384cafc 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -202,6 +202,9 @@
         notificationManager, InstrumentationService.NULL_SERVICE);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_addPluginToContextRoot() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -233,6 +236,9 @@
 //    pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_broadcastRequest_many() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -259,6 +265,9 @@
     pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_broadcastRequest_many_noContextRoot() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -283,6 +292,9 @@
     pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_broadcastWatchEvent() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -306,6 +318,9 @@
     pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_pluginsForContextRoot_multiple() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -333,6 +348,9 @@
     pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_pluginsForContextRoot_one() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -349,6 +367,9 @@
     pkg1Dir.deleteSync(recursive: true);
   }
 
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_removedContextRoot() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkgPath = pkg1Dir.resolveSymbolicLinksSync();
@@ -364,6 +385,9 @@
   }
 
   @TestTimeout(const Timeout.factor(4))
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_restartPlugins() async {
     io.Directory pkg1Dir = io.Directory.systemTemp.createTempSync('pkg1');
     String pkg1Path = pkg1Dir.resolveSymbolicLinksSync();
@@ -514,6 +538,9 @@
 
 @reflectiveTest
 class PluginSessionFromDiskTest extends PluginTestSupport {
+  @SkippedTest(
+      reason: 'flaky timeouts',
+      issue: 'https://github.com/dart-lang/sdk/issues/38629')
   test_start_notRunning() async {
     await withPlugin(test: (String pluginPath) async {
       String packagesPath = path.join(pluginPath, '.packages');
diff --git a/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart b/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
new file mode 100644
index 0000000..13f5ab3
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/add_diagnostic_property_reference_test.dart
@@ -0,0 +1,214 @@
+// Copyright (c) 2019, 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:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/linter/lint_names.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(AddDiagnosticPropertyReferenceTest);
+  });
+}
+
+@reflectiveTest
+class AddDiagnosticPropertyReferenceTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.ADD_DIAGNOSTIC_PROPERTY_REFERENCE;
+
+  @override
+  String get lintCode => LintNames.diagnostic_describe_all_properties;
+
+  test_boolField_debugFillProperties() async {
+    await resolveTestUnit('''
+class Absorber extends Widget {
+  bool get absorbing => _absorbing;
+  bool _absorbing;
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+  }
+}
+''');
+    await assertHasFix('''
+class Absorber extends Widget {
+  bool get absorbing => _absorbing;
+  bool _absorbing;
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+    properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+  }
+}
+''');
+  }
+
+  test_boolField_debugFillProperties_empty() async {
+    await resolveTestUnit('''
+class Absorber extends Widget {
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+  }
+}
+''');
+    await assertHasFix('''
+class Absorber extends Widget {
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+  }
+}
+''');
+  }
+
+  test_boolField_debugFillProperties_empty_customParamName() async {
+    await resolveTestUnit('''
+class Absorber extends Widget {
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder props) {
+  }
+}
+''');
+    await assertHasFix('''
+class Absorber extends Widget {
+  bool /*LINT*/ignoringSemantics;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder props) {
+    props.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));
+  }
+}
+''');
+  }
+
+  test_boolGetter_debugFillProperties() async {
+    await resolveTestUnit('''
+class Absorber extends Widget {
+  bool get /*LINT*/absorbing => _absorbing;
+  bool _absorbing;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+  }
+}
+''');
+    await assertHasFix('''
+class Absorber extends Widget {
+  bool get /*LINT*/absorbing => _absorbing;
+  bool _absorbing;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));
+  }
+}
+''');
+  }
+
+  test_doubleField_debugFillProperties() async {
+    await resolveTestUnit('''
+class A extends Widget {
+  double /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+  }
+}
+''');
+    await assertHasFix('''
+class A extends Widget {
+  double /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(DoubleProperty('field', field));
+  }
+}
+''');
+  }
+
+  test_enumField_debugFillProperties() async {
+    await resolveTestUnit('''
+enum foo {bar}
+class A extends Widget {
+  foo /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+  }
+}
+''');
+    await assertHasFix('''
+enum foo {bar}
+class A extends Widget {
+  foo /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(EnumProperty('field', field));
+  }
+}
+''');
+  }
+
+  test_intField_debugFillProperties() async {
+    await resolveTestUnit('''
+class A extends Widget {
+  int /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+  }
+}
+''');
+    await assertHasFix('''
+class A extends Widget {
+  int /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(IntProperty('field', field));
+  }
+}
+''');
+  }
+
+  test_stringField_debugFillProperties() async {
+    await resolveTestUnit('''
+class A extends Widget {
+  String /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+  }
+}
+''');
+    await assertHasFix('''
+class A extends Widget {
+  String /*LINT*/field;
+  @override
+  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
+    super.debugFillProperties(properties);
+    properties.add(StringProperty('field', field));
+  }
+}
+''');
+  }
+
+  // todo (pq): tests for no debugFillProperties method
+  // todo (pq): consider a test for a body w/ no CR
+  // todo (pq): support for ColorProperty -- for Color
+  // todo (pq): support for IterableProperty -- any iterable
+  // todo (pq): support for TransformProperty -- Matrix4
+  // todo (pq): support for DiagnosticsProperty for any T that doesn't match one of the other cases
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 3509418..3c6ba74 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -8,6 +8,8 @@
 import 'add_await_test.dart' as add_await;
 import 'add_const_test.dart' as add_const;
 import 'add_curly_braces_test.dart' as add_curly_braces;
+import 'add_diagnostic_property_reference_test.dart'
+    as add_diagnostic_property_reference;
 import 'add_explicit_cast_test.dart' as add_explicit_cast;
 import 'add_field_formal_parameters_test.dart' as add_field_formal_parameters;
 import 'add_missing_enum_case_clauses_test.dart'
@@ -140,6 +142,7 @@
     add_await.main();
     add_const.main();
     add_curly_braces.main();
+    add_diagnostic_property_reference.main();
     add_explicit_cast.main();
     add_field_formal_parameters.main();
     add_missing_enum_case_clauses.main();
diff --git a/pkg/analyzer/analysis_options.yaml b/pkg/analyzer/analysis_options.yaml
index 3fa0592..59199b3 100644
--- a/pkg/analyzer/analysis_options.yaml
+++ b/pkg/analyzer/analysis_options.yaml
@@ -10,14 +10,10 @@
     # Ignoring "style" lint rules from pedantic for now. There are pre-existing
     # violations that need to be cleaned up. Each one can be cleaned up and
     # enabled according to the value provided.
-    avoid_init_to_null: ignore
     avoid_return_types_on_setters: ignore
     curly_braces_in_flow_control_structures: ignore
     empty_catches: ignore
     prefer_iterable_wheretype: ignore
-    prefer_contains: ignore
-    # TODO(srawlins): Fix existing violations!
-    no_duplicate_case_values: ignore
     # TODO(srawlins): At the time of writing, 230 violations in lib/. The fix
     # is mechanical, via `dartfmt --fix-named-default-separator`.
     prefer_equal_for_default_values: ignore
diff --git a/pkg/analyzer/lib/dart/analysis/context_locator.dart b/pkg/analyzer/lib/dart/analysis/context_locator.dart
index d2c4cd3..2211439 100644
--- a/pkg/analyzer/lib/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/dart/analysis/context_locator.dart
@@ -39,9 +39,9 @@
   List<AnalysisContext> locateContexts(
       {@required List<String> includedPaths,
       List<String> excludedPaths: const <String>[],
-      String optionsFile: null,
-      String packagesFile: null,
-      String sdkPath: null});
+      String optionsFile,
+      String packagesFile,
+      String sdkPath});
 
   /// Return a list of the context roots that should be used to analyze the
   /// files that are included by the list of [includedPaths] and not excluded by
@@ -57,7 +57,7 @@
   /// found by looking in the directories containing the context roots.
   List<ContextRoot> locateRoots(
       {@required List<String> includedPaths,
-      List<String> excludedPaths: null,
-      String optionsFile: null,
-      String packagesFile: null});
+      List<String> excludedPaths,
+      String optionsFile,
+      String packagesFile});
 }
diff --git a/pkg/analyzer/lib/exception/exception.dart b/pkg/analyzer/lib/exception/exception.dart
index e475c04..73b1a5d 100644
--- a/pkg/analyzer/lib/exception/exception.dart
+++ b/pkg/analyzer/lib/exception/exception.dart
@@ -21,7 +21,7 @@
    * Initialize a newly created exception to have the given [message] and
    * [cause].
    */
-  AnalysisException([this.message = 'Exception', this.cause = null]);
+  AnalysisException([this.message = 'Exception', this.cause]);
 
   String toString() {
     StringBuffer buffer = new StringBuffer();
diff --git a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
index 5d3e616..2566e22 100644
--- a/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/src/analysis_options/analysis_options_provider.dart
@@ -41,7 +41,7 @@
   /// The given [root] directory will be searched first. If no file is found and
   /// if [crawlUp] is `true`, then enclosing directories will be searched.
   File getOptionsFile(Folder root, {bool crawlUp: false}) {
-    Resource resource = null;
+    Resource resource;
     for (Folder folder = root; folder != null; folder = folder.parent) {
       resource = folder.getChild(AnalysisEngine.ANALYSIS_OPTIONS_FILE);
       if (resource.exists) {
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 4a58ff8..a1840b0 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -78,7 +78,7 @@
    * create their own drivers with the same tools, in theory. Here as a stopgap
    * until the official plugin API is complete
    */
-  static Function onCreateAnalysisDriver = null;
+  static Function onCreateAnalysisDriver;
 
   /**
    * The [ResourceProvider] by which paths are converted into [Resource]s.
diff --git a/pkg/analyzer/lib/src/context/source.dart b/pkg/analyzer/lib/src/context/source.dart
index 71abce1..07a26ee 100644
--- a/pkg/analyzer/lib/src/context/source.dart
+++ b/pkg/analyzer/lib/src/context/source.dart
@@ -251,7 +251,7 @@
 
     // Check .packages and update target and actual URIs as appropriate.
     if (_packages != null && containedUri.scheme == 'package') {
-      Uri packageUri = null;
+      Uri packageUri;
       try {
         packageUri =
             _packages.resolve(containedUri, notFound: (Uri packageUri) => null);
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
index 52a6a24..1f6826a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_locator.dart
@@ -76,9 +76,9 @@
   List<AnalysisContext> locateContexts(
       {@required List<String> includedPaths,
       List<String> excludedPaths: const <String>[],
-      String optionsFile: null,
-      String packagesFile: null,
-      String sdkPath: null}) {
+      String optionsFile,
+      String packagesFile,
+      String sdkPath}) {
     List<ContextRoot> roots = locateRoots(
         includedPaths: includedPaths,
         excludedPaths: excludedPaths,
@@ -120,9 +120,9 @@
   @override
   List<ContextRoot> locateRoots(
       {@required List<String> includedPaths,
-      List<String> excludedPaths: null,
-      String optionsFile: null,
-      String packagesFile: null}) {
+      List<String> excludedPaths,
+      String optionsFile,
+      String packagesFile}) {
     //
     // Compute the list of folders and files that are to be included.
     //
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index c71d4d3..f28a361 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -95,6 +95,11 @@
   /// zero, we stop writing any new exception contexts in this process.
   static int allowedNumberOfContextsToWrite = 10;
 
+  /// Whether summary2 should be used to resynthesize elements.
+  @Deprecated('Clients should assume summary2 is used.  '
+      'Summary1 support has been removed.')
+  static bool get useSummary2 => true;
+
   /// The scheduler that schedules analysis work in this, and possibly other
   /// analysis drivers.
   final AnalysisDriverScheduler _scheduler;
@@ -1592,7 +1597,7 @@
   }
 
   void _reportException(String path, exception, StackTrace stackTrace) {
-    String contextKey = null;
+    String contextKey;
     if (exception is _ExceptionState) {
       var state = exception as _ExceptionState;
       exception = state.exception;
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
index 06b9e65..d4c2171 100644
--- a/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/experiments.g.dart
@@ -27,7 +27,7 @@
 List<bool> _buildExperimentalFlagsArray() => <bool>[
       true, // constant-update-2018
       true, // control-flow-collections
-      IsEnabledByDefault.extension_methods,
+      true, // extension-methods
       IsEnabledByDefault.non_nullable,
       true, // set-literals
       true, // spread-collections
@@ -95,7 +95,8 @@
       EnableString.extension_methods,
       IsEnabledByDefault.extension_methods,
       IsExpired.extension_methods,
-      'Extension Methods');
+      'Extension Methods',
+      firstSupportedVersion: '2.6.0');
 
   static const non_nullable = const ExperimentalFeature(
       3,
@@ -160,7 +161,7 @@
   static const bool control_flow_collections = true;
 
   /// Default state of the experiment "extension-methods"
-  static const bool extension_methods = false;
+  static const bool extension_methods = true;
 
   /// Default state of the experiment "non-nullable"
   static const bool non_nullable = false;
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 80d34b3..cfb2a93 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -507,7 +507,7 @@
 
     ErrorReporter libraryErrorReporter = _getErrorReporter(_library);
 
-    LibraryIdentifier libraryNameNode = null;
+    LibraryIdentifier libraryNameNode;
     var seenPartSources = new Set<Source>();
     var directivesToResolve = <Directive>[];
     int partIndex = 0;
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index d38a651..dc4cc41 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -876,7 +876,7 @@
     }
     // Create locations for every usage of the element.
     List<SearchResult> results = <SearchResult>[];
-    CompilationUnitElement enclosingUnitElement = null;
+    CompilationUnitElement enclosingUnitElement;
     for (;
         i < index.usedElements.length && index.usedElements[i] == elementId;
         i++) {
@@ -956,7 +956,7 @@
 
     // Create results for every usage of the name.
     List<SearchResult> results = <SearchResult>[];
-    CompilationUnitElement enclosingUnitElement = null;
+    CompilationUnitElement enclosingUnitElement;
     for (; i < index.usedNames.length && index.usedNames[i] == nameId; i++) {
       IndexRelationKind relationKind = index.usedNameKinds[i];
       SearchResultKind resultKind = relationToResultKind[relationKind];
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 9dd4e72..4e5e5ac 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -716,7 +716,7 @@
   /// representing the parameter to which the value of the right operand will be
   /// bound. Otherwise, return `null`.
   ParameterElement get _staticParameterElementForRightHandSide {
-    ExecutableElement executableElement = null;
+    ExecutableElement executableElement;
     if (staticElement != null) {
       executableElement = staticElement;
     } else {
@@ -5938,7 +5938,7 @@
   /// If this expression is both in a getter and setter context, the
   /// [AuxiliaryElements] will be set to hold onto the static element from the
   /// getter context.
-  AuxiliaryElements auxiliaryElements = null;
+  AuxiliaryElements auxiliaryElements;
 
   /// Initialize a newly created index expression.
   IndexExpressionImpl.forCascade(
@@ -8921,7 +8921,7 @@
   /// If this expression is both in a getter and setter context, the
   /// [AuxiliaryElements] will be set to hold onto the static element from the
   /// getter context.
-  AuxiliaryElements auxiliaryElements = null;
+  AuxiliaryElements auxiliaryElements;
 
   @override
   List<DartType> tearOffTypeArgumentTypes;
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 6efad5a..67c908d 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -6189,7 +6189,7 @@
 
   @override
   void visitFormalParameterList(FormalParameterList node) {
-    String groupEnd = null;
+    String groupEnd;
     _writer.print('(');
     NodeList<FormalParameter> parameters = node.parameters;
     int size = parameters.length;
@@ -7496,7 +7496,7 @@
 
   @override
   void visitFormalParameterList(FormalParameterList node) {
-    String groupEnd = null;
+    String groupEnd;
     sink.write('(');
     NodeList<FormalParameter> parameters = node.parameters;
     int size = parameters.length;
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 9f37e6b..0d81332 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -231,7 +231,7 @@
     // type.
     NodeList<SwitchMember> switchMembers = node.members;
     bool foundError = false;
-    DartType firstType = null;
+    DartType firstType;
     for (SwitchMember switchMember in switchMembers) {
       if (switchMember is SwitchCase) {
         Expression expression = switchMember.expression;
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 0f2f144..42f7ab6 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -585,8 +585,8 @@
       while (baseParameter is ParameterMember) {
         baseParameter = (baseParameter as ParameterMember).baseElement;
       }
-      DartObjectImpl argumentValue = null;
-      AstNode errorTarget = null;
+      DartObjectImpl argumentValue;
+      AstNode errorTarget;
       if (baseParameter.isNamed) {
         argumentValue = namedValues[baseParameter.name];
         errorTarget = namedNodes[baseParameter.name];
@@ -652,8 +652,8 @@
     ConstantVisitor initializerVisitor = new ConstantVisitor(
         this, externalErrorReporter,
         lexicalEnvironment: parameterMap);
-    String superName = null;
-    NodeList<Expression> superArguments = null;
+    String superName;
+    NodeList<Expression> superArguments;
     for (var i = 0; i < initializers.length; i++) {
       var initializer = initializers[i];
       if (initializer is ConstructorFieldInitializer) {
@@ -875,11 +875,7 @@
       // fixed.
       return true;
     }
-    // TODO(scheglov ) Switch to using this, but not now, dartbug.com/33441
-    if (typeSystem.isSubtypeOf(objType, type)) {
-      return true;
-    }
-    return objType.isSubtypeOf(type);
+    return typeSystem.isSubtypeOf(objType, type);
   }
 
   /// Determine whether the given string is a valid name for a public symbol
@@ -1018,7 +1014,7 @@
 
   @override
   DartObjectImpl visitAdjacentStrings(AdjacentStrings node) {
-    DartObjectImpl result = null;
+    DartObjectImpl result;
     for (StringLiteral string in node.strings) {
       if (result == null) {
         result = string.accept(this);
@@ -1432,7 +1428,7 @@
 
   @override
   DartObjectImpl visitStringInterpolation(StringInterpolation node) {
-    DartObjectImpl result = null;
+    DartObjectImpl result;
     bool first = true;
     for (InterpolationElement element in node.elements) {
       if (first) {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 98921f2..c87f158 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1272,7 +1272,7 @@
   /// application classes which have been visited on the way to reaching this
   /// one (this is used to detect circularities).
   List<ConstructorElement> _computeMixinAppConstructors(
-      [List<ClassElementImpl> visitedClasses = null]) {
+      [List<ClassElementImpl> visitedClasses]) {
     // First get the list of constructors of the superclass which need to be
     // forwarded to this class.
     Iterable<ConstructorElement> constructorsToForward;
@@ -1654,7 +1654,7 @@
   /// A table mapping the offset of a directive to the annotations associated
   /// with that directive, or `null` if none of the annotations in the
   /// compilation unit have annotations.
-  Map<int, List<ElementAnnotation>> annotationMap = null;
+  Map<int, List<ElementAnnotation>> annotationMap;
 
   /// A list containing all of the top-level accessors (getters and setters)
   /// contained in this compilation unit.
@@ -4766,7 +4766,7 @@
         buffer.write('>');
       }
       buffer.write('(');
-      String closing = null;
+      String closing;
       ParameterKind kind = ParameterKind.REQUIRED;
       int parameterCount = parameters.length;
       for (int i = 0; i < parameterCount; i++) {
@@ -6965,7 +6965,7 @@
   /// if not present.  If _libraryCycle is set, then the _libraryCycle field
   /// for all libraries reachable from this library in the import/export graph
   /// is also set.
-  List<LibraryElement> _libraryCycle = null;
+  List<LibraryElement> _libraryCycle;
 
   /// A list containing all of the compilation units that are included in this
   /// library using a `part` directive.
@@ -7434,7 +7434,7 @@
         // Pop the elements, and share the component across all
         // of the elements.
         List<LibraryElement> component = <LibraryElement>[];
-        LibraryElementImpl cur = null;
+        LibraryElementImpl cur;
         do {
           cur = stack.removeLast();
           active.remove(cur);
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
index b27a187..63238fc 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager2.dart
@@ -344,7 +344,7 @@
   List<Conflict> _findMostSpecificFromNamedCandidates(
       Map<Name, FunctionType> map,
       Map<Name, List<FunctionType>> namedCandidates) {
-    List<Conflict> conflicts = null;
+    List<Conflict> conflicts;
 
     for (var name in namedCandidates.keys) {
       if (map.containsKey(name)) {
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index 1c9a60d..f457b8a 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -340,7 +340,7 @@
   List<Conflict> _findMostSpecificFromNamedCandidates(
       Map<Name, ExecutableElement> map,
       Map<Name, List<ExecutableElement>> namedCandidates) {
-    List<Conflict> conflicts = null;
+    List<Conflict> conflicts;
 
     for (var name in namedCandidates.keys) {
       if (map.containsKey(name)) {
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 6d27b90..737047d 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -608,7 +608,7 @@
       buffer.write('>');
     }
     buffer.write('(');
-    String closing = null;
+    String closing;
     ParameterKind kind = ParameterKind.REQUIRED;
     int parameterCount = parameters.length;
     for (int i = 0; i < parameterCount; i++) {
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 68a0c7c..c1339c9 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1259,7 +1259,7 @@
   /**
    * The version of [element] for which members are cached.
    */
-  int _versionOfCachedMembers = null;
+  int _versionOfCachedMembers;
 
   /**
    * Cached [ConstructorElement]s - members or raw elements.
@@ -2847,8 +2847,6 @@
  * A concrete implementation of a [TypeParameterType].
  */
 class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
-  static bool _comparingBounds = false;
-
   @override
   final NullabilitySuffix nullabilitySuffix;
 
@@ -2874,20 +2872,10 @@
 
   @override
   bool operator ==(Object other) {
-    if (other is TypeParameterTypeImpl && element == other.element) {
-      if (_comparingBounds) {
-        // If we're comparing bounds already, then we only need type variable
-        // equality.
-        return true;
-      }
-      _comparingBounds = true;
-      try {
-        return bound == other.bound;
-      } finally {
-        _comparingBounds = false;
-      }
+    if (identical(other, this)) {
+      return true;
     }
-    return false;
+    return other is TypeParameterTypeImpl && other.element == element;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
index cf5639a..756feb8 100644
--- a/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/ast_rewrite.dart
@@ -4,13 +4,9 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
-import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
-import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -20,7 +16,6 @@
 /// A visitor that will re-write an AST to support the optional `new` and
 /// `const` feature.
 class AstRewriteVisitor extends ScopedVisitor {
-  final bool addConstKeyword;
   final TypeSystem typeSystem;
 
   /// Initialize a newly created visitor.
@@ -30,8 +25,7 @@
       Source source,
       TypeProvider typeProvider,
       AnalysisErrorListener errorListener,
-      {Scope nameScope,
-      this.addConstKeyword: false})
+      {Scope nameScope})
       : super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope);
 
@@ -60,7 +54,7 @@
             astFactory.constructorName(typeName, null, null);
         InstanceCreationExpression instanceCreationExpression =
             astFactory.instanceCreationExpression(
-                _getKeyword(node), constructorName, node.argumentList);
+                null, constructorName, node.argumentList);
         NodeReplacer.replace(node, instanceCreationExpression);
       } else if (element is ExtensionElement) {
         ExtensionOverride extensionOverride = astFactory.extensionOverride(
@@ -94,7 +88,7 @@
           // TODO(scheglov) I think we should drop "typeArguments" below.
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
-                  _getKeyword(node), constructorName, node.argumentList,
+                  null, constructorName, node.argumentList,
                   typeArguments: typeArguments);
           NodeReplacer.replace(node, instanceCreationExpression);
         }
@@ -113,7 +107,7 @@
               astFactory.constructorName(typeName, null, null);
           InstanceCreationExpression instanceCreationExpression =
               astFactory.instanceCreationExpression(
-                  _getKeyword(node), constructorName, node.argumentList);
+                  null, constructorName, node.argumentList);
           NodeReplacer.replace(node, instanceCreationExpression);
         } else if (prefixedElement is ExtensionElement) {
           PrefixedIdentifier extensionName =
@@ -147,49 +141,11 @@
                 astFactory.constructorName(typeName, node.operator, methodName);
             InstanceCreationExpression instanceCreationExpression =
                 astFactory.instanceCreationExpression(
-                    _getKeyword(node), constructorName, node.argumentList);
+                    null, constructorName, node.argumentList);
             NodeReplacer.replace(node, instanceCreationExpression);
           }
         }
       }
     }
   }
-
-  /// Return the token that should be used in the [InstanceCreationExpression]
-  /// that corresponds to the given invocation [node].
-  Token _getKeyword(MethodInvocation node) {
-    return addConstKeyword
-        ? new KeywordToken(Keyword.CONST, node.offset)
-        : null;
-  }
-
-  /// Return the type of the given class [element] after substituting any type
-  /// arguments from the list of [typeArguments] for the class' type parameters.
-  static InterfaceType getType(TypeSystem typeSystem, ClassElement element,
-      TypeArgumentList typeArguments) {
-    DartType type = element.type;
-
-    List<TypeParameterElement> typeParameters = element.typeParameters;
-    if (typeParameters.isEmpty) {
-      return type;
-    }
-
-    if (typeArguments == null) {
-      return typeSystem.instantiateToBounds(type);
-    }
-
-    List<DartType> argumentTypes;
-    if (typeArguments.arguments.length == typeParameters.length) {
-      argumentTypes = typeArguments.arguments
-          .map((TypeAnnotation argument) => argument.type)
-          .toList();
-    } else {
-      argumentTypes = List<DartType>.filled(
-          typeParameters.length, DynamicTypeImpl.instance);
-    }
-    List<DartType> parameterTypes = typeParameters
-        .map((TypeParameterElement parameter) => parameter.type)
-        .toList();
-    return type.substitute2(argumentTypes, parameterTypes);
-  }
 }
diff --git a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
index 4ac8a57..56e6382 100644
--- a/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/method_invocation_resolver.dart
@@ -311,7 +311,7 @@
       ClassElement classElement, SimpleIdentifier propertyName) {
     // TODO(scheglov) Replace with class hierarchy.
     String name = propertyName.name;
-    Element element = null;
+    Element element;
     if (propertyName.inSetterContext()) {
       element = classElement.getSetter(name);
     }
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index ef8de3a..9304c38 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -1035,7 +1035,7 @@
    * A table mapping names that are defined in this scope to the element
    * representing the thing declared with that name.
    */
-  Map<String, Element> _definedNames = null;
+  Map<String, Element> _definedNames;
 
   /**
    * Return the scope in which this scope is lexically enclosed.
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index 6bf0d08..b3432d7 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -616,8 +616,8 @@
    */
   LibraryMap initialLibraryMap(bool useDart2jsPaths) {
     List<String> searchedPaths = <String>[];
-    var lastStackTrace = null;
-    var lastException = null;
+    StackTrace lastStackTrace;
+    Object lastException;
     for (File librariesFile in _libraryMapLocations) {
       try {
         String contents = librariesFile.readAsStringSync();
diff --git a/pkg/analyzer/lib/src/error/inheritance_override.dart b/pkg/analyzer/lib/src/error/inheritance_override.dart
index 8ece3f2..ac9b421 100644
--- a/pkg/analyzer/lib/src/error/inheritance_override.dart
+++ b/pkg/analyzer/lib/src/error/inheritance_override.dart
@@ -189,7 +189,7 @@
     _checkForMismatchedAccessorTypes(interface);
 
     if (!classElement.isAbstract) {
-      List<ExecutableElement> inheritedAbstract = null;
+      List<ExecutableElement> inheritedAbstract;
 
       for (var name in interface.map.keys) {
         if (!name.isAccessibleFor(libraryUri)) {
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index df889e0..5b76714 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -1747,6 +1747,15 @@
     // extensions. They are invalid and the parser has already reported an
     // error at this point. In the future, we should include them in order
     // to get navigation, search, etc.
+    pop(); // body
+    pop(); // initializers
+    pop(); // separator
+    pop(); // parameters
+    pop(); // typeParameters
+    pop(); // name
+    pop(); // returnType
+    pop(); // modifiers
+    pop(); // metadata
   }
 
   @override
@@ -3593,7 +3602,7 @@
 
   /// Return the token that is lexically first.
   Token get beginToken {
-    Token firstToken = null;
+    Token firstToken;
     for (Token token in [
       abstractKeyword,
       externalKeyword,
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index a8dfa2e..2813216 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -774,6 +774,6 @@
   /// and [cause].
   _ElementMismatchException(
       CompilationUnitElement compilationUnit, Element element,
-      [CaughtException cause = null])
+      [CaughtException cause])
       : super('Element mismatch in $compilationUnit at $element', cause);
 }
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index fd7e626..17b73d5 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -19,9 +19,7 @@
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
-import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/resolver/extension_member_resolver.dart';
 import 'package:analyzer/src/dart/resolver/method_invocation_resolver.dart';
 import 'package:analyzer/src/dart/resolver/resolution_result.dart';
@@ -711,7 +709,7 @@
               [memberName, element.name]);
         }
         if (propertyName.inGetterContext()) {
-          PropertyAccessorElement getter = result.getter;
+          ExecutableElement getter = result.getter;
           if (getter == null) {
             _resolver.errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.UNDEFINED_EXTENSION_GETTER,
@@ -1101,6 +1099,16 @@
     return _resolveTypeParameter(type);
   }
 
+  InterfaceType _instantiateAnnotationClass(ClassElement element) {
+    return element.instantiate(
+      typeArguments: List.filled(
+        element.typeParameters.length,
+        _dynamicType,
+      ),
+      nullabilitySuffix: _resolver.noneOrStarSuffix,
+    );
+  }
+
   /**
    * Check for a generic method & apply type arguments if any were passed.
    */
@@ -1254,44 +1262,6 @@
     _resolver.errorReporter.reportErrorForToken(errorCode, token, arguments);
   }
 
-  /// Resolve the [constructorName] to the constructor in the class [element].
-  /// Perform inference using [argumentList].
-  ConstructorElement _resolveAnnotationConstructor(
-    ClassElement element,
-    String constructorName,
-    ArgumentList argumentList,
-  ) {
-    var constructor = constructorName != null
-        ? element.getNamedConstructor(constructorName)
-        : element.unnamedConstructor;
-    if (constructor == null) {
-      return null;
-    }
-    if (!constructor.isAccessibleIn(_definingLibrary)) {
-      return null;
-    }
-
-    var typeParameters = element.typeParameters;
-    if (typeParameters.isEmpty) {
-      return constructor;
-    }
-
-    var typeArgs = _resolver.typeSystem.inferGenericFunctionOrType(
-      typeParameters: typeParameters,
-      parameters: constructor.parameters,
-      declaredReturnType: null,
-      argumentTypes: argumentList.arguments.map((a) => a.staticType).toList(),
-      contextReturnType: null,
-      isConst: true,
-      errorReporter: _resolver.errorReporter,
-      errorNode: argumentList,
-    );
-    return ExecutableMember.from2(
-      constructor,
-      Substitution.fromPairs(typeParameters, typeArgs),
-    );
-  }
-
   void _resolveAnnotationConstructorInvocationArguments(
       Annotation annotation, ConstructorElement constructor) {
     ArgumentList argumentList = annotation.arguments;
@@ -1338,11 +1308,8 @@
       }
       // Class(args)
       if (element1 is ClassElement) {
-        constructor = _resolveAnnotationConstructor(
-          element1,
-          null,
-          annotation.arguments,
-        );
+        constructor = _instantiateAnnotationClass(element1)
+            .lookUpConstructor(null, _definingLibrary);
       } else if (element1 == null) {
         undefined = true;
       }
@@ -1370,11 +1337,8 @@
       }
       // Class.constructor(args)
       if (element1 is ClassElement) {
-        constructor = _resolveAnnotationConstructor(
-          element1,
-          nameNode2.name,
-          annotation.arguments,
-        );
+        constructor = _instantiateAnnotationClass(element1)
+            .lookUpConstructor(nameNode2.name, _definingLibrary);
         nameNode2.staticElement = constructor;
       }
       if (element1 == null && element2 == null) {
@@ -1399,11 +1363,8 @@
           return;
         }
         // prefix.Class.constructor(args)
-        constructor = _resolveAnnotationConstructor(
-          element2,
-          name3,
-          annotation.arguments,
-        );
+        constructor = _instantiateAnnotationClass(element2)
+            .lookUpConstructor(name3, _definingLibrary);
         nameNode3.staticElement = constructor;
       } else if (element2 == null) {
         undefined = true;
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 53038fc..b28a0af 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -279,7 +279,7 @@
    * The elements that will be defined later in the current scope, but right
    * now are not declared.
    */
-  HiddenElements _hiddenElements = null;
+  HiddenElements _hiddenElements;
 
   /**
    * A list of types used by the [CompileTimeErrorCode.EXTENDS_DISALLOWED_CLASS]
@@ -2058,7 +2058,7 @@
    */
   void _checkForAssignmentToFinal(Expression expression) {
     // prepare element
-    Element element = null;
+    Element element;
     AstNode highlightedNode = expression;
     if (expression is Identifier) {
       element = expression.staticElement;
@@ -3650,7 +3650,7 @@
     ExecutableElement accessorElement =
         accessorDeclaration.declaredElement as ExecutableElement;
     if (accessorElement is PropertyAccessorElement) {
-      PropertyAccessorElement counterpartAccessor = null;
+      PropertyAccessorElement counterpartAccessor;
       if (accessorElement.isGetter) {
         counterpartAccessor = accessorElement.correspondingSetter;
       } else {
@@ -3667,8 +3667,8 @@
         return;
       }
       // Default of null == no accessor or no type (dynamic)
-      DartType getterType = null;
-      DartType setterType = null;
+      DartType getterType;
+      DartType setterType;
       // Get an existing counterpart accessor if any.
       if (accessorElement.isGetter) {
         getterType = _getGetterType(accessorElement);
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 8e6d623..58b6393 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -560,13 +560,13 @@
   Annotation parseAnnotation() {
     Token atSign = getAndAdvance();
     Identifier name = parsePrefixedIdentifier();
-    Token period = null;
-    SimpleIdentifier constructorName = null;
+    Token period;
+    SimpleIdentifier constructorName;
     if (_matches(TokenType.PERIOD)) {
       period = getAndAdvance();
       constructorName = parseSimpleIdentifier();
     }
-    ArgumentList arguments = null;
+    ArgumentList arguments;
     if (_matches(TokenType.OPEN_PAREN)) {
       arguments = parseArgumentList();
     }
@@ -690,7 +690,7 @@
     if (_matches(TokenType.COMMA)) {
       comma = getAndAdvance();
       if (_matches(TokenType.CLOSE_PAREN)) {
-        comma = null;
+        comma;
       } else {
         message = parseExpression2();
         if (_matches(TokenType.COMMA)) {
@@ -939,7 +939,7 @@
   ///         'break' identifier? ';'
   Statement parseBreakStatement() {
     Token breakKeyword = getAndAdvance();
-    SimpleIdentifier label = null;
+    SimpleIdentifier label;
     if (_matchesIdentifier()) {
       label = _parseSimpleIdentifierUnchecked();
     }
@@ -968,8 +968,8 @@
   ///         assignmentOperator expressionWithoutCascade
   Expression parseCascadeSection() {
     Token period = getAndAdvance();
-    Expression expression = null;
-    SimpleIdentifier functionName = null;
+    Expression expression;
+    SimpleIdentifier functionName;
     if (_matchesIdentifier()) {
       functionName = _parseSimpleIdentifierUnchecked();
     } else if (_currentToken.type == TokenType.OPEN_SQUARE_BRACKET) {
@@ -981,7 +981,7 @@
         Token rightBracket = _expect(TokenType.CLOSE_SQUARE_BRACKET);
         expression = astFactory.indexExpressionForCascade(
             period, leftBracket, index, rightBracket);
-        period = null;
+        period;
       } finally {
         _inInitializer = wasInInitializer;
       }
@@ -998,8 +998,8 @@
         if (functionName != null) {
           expression = astFactory.methodInvocation(expression, period,
               functionName, typeArguments, parseArgumentList());
-          period = null;
-          functionName = null;
+          period;
+          functionName;
         } else if (expression == null) {
           // It should not be possible to get here.
           expression = astFactory.methodInvocation(expression, period,
@@ -1011,7 +1011,7 @@
       } while (_isLikelyArgumentList());
     } else if (functionName != null) {
       expression = astFactory.propertyAccess(expression, period, functionName);
-      period = null;
+      period;
     }
     assert(expression != null);
     bool progress = true;
@@ -1065,7 +1065,7 @@
     Token keyword = getAndAdvance();
     SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
     String className = name.name;
-    TypeParameterList typeParameters = null;
+    TypeParameterList typeParameters;
     TokenType type = _currentToken.type;
     if (type == TokenType.LT) {
       typeParameters = parseTypeParameterList();
@@ -1084,9 +1084,9 @@
     // generate errors if they are not in the order required by the
     // specification.
     //
-    ExtendsClause extendsClause = null;
-    WithClause withClause = null;
-    ImplementsClause implementsClause = null;
+    ExtendsClause extendsClause;
+    WithClause withClause;
+    ImplementsClause implementsClause;
     bool foundClause = true;
     while (foundClause) {
       Keyword keyword = _currentToken.keyword;
@@ -1136,7 +1136,7 @@
     //
     // Look for and skip over the extra-lingual 'native' specification.
     //
-    NativeClause nativeClause = null;
+    NativeClause nativeClause;
     if (_matchesKeyword(Keyword.NATIVE) &&
         _tokenMatches(_peek(), TokenType.STRING)) {
       nativeClause = _parseNativeClause();
@@ -1144,9 +1144,9 @@
     //
     // Parse the body of the class.
     //
-    Token leftBracket = null;
-    List<ClassMember> members = null;
-    Token rightBracket = null;
+    Token leftBracket;
+    List<ClassMember> members;
+    Token rightBracket;
     if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
       leftBracket = getAndAdvance();
       members = _parseClassMembers(className, _getEndToken(leftBracket));
@@ -1367,9 +1367,9 @@
           parseSimpleIdentifier(allowKeyword: true, isDeclaration: true),
           parseFormalParameterList());
     } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
-      TypeName returnType = null;
+      TypeName returnType;
       SimpleIdentifier methodName = parseSimpleIdentifier(isDeclaration: true);
-      TypeParameterList typeParameters = null;
+      TypeParameterList typeParameters;
       FormalParameterList parameters = parseFormalParameterList();
       if (_matches(TokenType.COLON) ||
           modifiers.factoryKeyword != null ||
@@ -1484,7 +1484,7 @@
     } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
       SimpleIdentifier methodName =
           _parseSimpleIdentifierUnchecked(isDeclaration: true);
-      TypeParameterList typeParameters = null;
+      TypeParameterList typeParameters;
       FormalParameterList parameters = parseFormalParameterList();
       if (methodName.name == className) {
         _reportErrorForNode(ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE, type);
@@ -1551,7 +1551,7 @@
   ///         'show' identifier (',' identifier)*
   ///       | 'hide' identifier (',' identifier)*
   List<Combinator> parseCombinators() {
-    List<Combinator> combinators = null;
+    List<Combinator> combinators;
     while (true) {
       Combinator combinator = parseCombinator();
       if (combinator == null) {
@@ -1575,7 +1575,7 @@
     // TODO(brianwilkerson) Consider making the creation of documentation
     // comments be lazy.
     List<DocumentationCommentToken> tokens = parseDocumentationCommentTokens();
-    List<Annotation> metadata = null;
+    List<Annotation> metadata;
     while (_matches(TokenType.AT)) {
       metadata ??= <Annotation>[];
       metadata.add(parseAnnotation());
@@ -1617,7 +1617,7 @@
         return astFactory.commentReference(
             null, astFactory.simpleIdentifier(syntheticToken));
       }
-      Token newKeyword = null;
+      Token newKeyword;
       if (_tokenMatchesKeyword(firstToken, Keyword.NEW)) {
         newKeyword = firstToken;
         firstToken = firstToken.next;
@@ -1715,7 +1715,7 @@
       // Skip GitHub code blocks.
       // https://help.github.com/articles/creating-and-highlighting-code-blocks/
       if (tokens.length != 1) {
-        if (comment.indexOf('```') != -1) {
+        if (comment.contains('```')) {
           isInGitHubCodeBlock = !isInGitHubCodeBlock;
         }
         if (isInGitHubCodeBlock) {
@@ -1800,7 +1800,7 @@
   ///       | topLevelDeclaration
   CompilationUnit parseCompilationUnit2() {
     Token firstToken = _currentToken;
-    ScriptTag scriptTag = null;
+    ScriptTag scriptTag;
     if (_matches(TokenType.SCRIPT_TAG)) {
       scriptTag = astFactory.scriptTag(getAndAdvance());
     }
@@ -2081,7 +2081,7 @@
       return parseFunctionDeclaration(
           commentAndMetadata, modifiers.externalKeyword, null);
     } else if (_tokenMatches(next, TokenType.OPEN_PAREN)) {
-      TypeName returnType = null;
+      TypeName returnType;
       _validateModifiersForTopLevelFunction(modifiers);
       return parseFunctionDeclaration(
           commentAndMetadata, modifiers.externalKeyword, returnType);
@@ -2196,8 +2196,8 @@
     Token ifKeyword = getAndAdvance();
     Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
     DottedName name = parseDottedName();
-    Token equalToken = null;
-    StringLiteral value = null;
+    Token equalToken;
+    StringLiteral value;
     if (_matches(TokenType.EQ_EQ)) {
       equalToken = getAndAdvance();
       value = parseStringLiteral();
@@ -2241,14 +2241,14 @@
   ///     fieldInitializer:
   ///         ('this' '.')? identifier '=' conditionalExpression cascadeSection*
   ConstructorFieldInitializer parseConstructorFieldInitializer(bool hasThis) {
-    Token keywordToken = null;
-    Token period = null;
+    Token keywordToken;
+    Token period;
     if (hasThis) {
       keywordToken = getAndAdvance();
       period = _expect(TokenType.PERIOD);
     }
     SimpleIdentifier fieldName = parseSimpleIdentifier();
-    Token equals = null;
+    Token equals;
     TokenType type = _currentToken.type;
     if (type == TokenType.EQ) {
       equals = getAndAdvance();
@@ -2298,8 +2298,8 @@
   ///         type ('.' identifier)?
   ConstructorName parseConstructorName() {
     TypeName type = parseTypeName(false);
-    Token period = null;
-    SimpleIdentifier name = null;
+    Token period;
+    SimpleIdentifier name;
     if (_matches(TokenType.PERIOD)) {
       period = getAndAdvance();
       name = parseSimpleIdentifier();
@@ -2319,7 +2319,7 @@
       _reportErrorForToken(
           ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, continueKeyword);
     }
-    SimpleIdentifier label = null;
+    SimpleIdentifier label;
     if (_matchesIdentifier()) {
       label = _parseSimpleIdentifierUnchecked();
     }
@@ -2373,7 +2373,7 @@
   ///         scriptTag? directive*
   CompilationUnit parseDirectives2() {
     Token firstToken = _currentToken;
-    ScriptTag scriptTag = null;
+    ScriptTag scriptTag;
     if (_matches(TokenType.SCRIPT_TAG)) {
       scriptTag = astFactory.scriptTag(getAndAdvance());
     }
@@ -2510,9 +2510,9 @@
   EnumDeclaration parseEnumDeclaration(CommentAndMetadata commentAndMetadata) {
     Token keyword = getAndAdvance();
     SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
-    Token leftBracket = null;
+    Token leftBracket;
     List<EnumConstantDeclaration> constants = <EnumConstantDeclaration>[];
-    Token rightBracket = null;
+    Token rightBracket;
     if (_matches(TokenType.OPEN_CURLY_BRACKET)) {
       leftBracket = getAndAdvance();
       if (_matchesIdentifier() || _matches(TokenType.AT)) {
@@ -2720,8 +2720,8 @@
   ///       | type
   FinalConstVarOrType parseFinalConstVarOrType(bool optional,
       {bool inFunctionType: false}) {
-    Token keywordToken = null;
-    TypeAnnotation type = null;
+    Token keywordToken;
+    TypeAnnotation type;
     Keyword keyword = _currentToken.keyword;
     if (keyword == Keyword.FINAL || keyword == Keyword.CONST) {
       keywordToken = getAndAdvance();
@@ -2755,7 +2755,7 @@
     } else {
       // Support parameters such as `(/*=K*/ key, /*=V*/ value)`
       // This is not supported if the type is required.
-      type = null;
+      type;
     }
     return new FinalConstVarOrType(keywordToken, type);
   }
@@ -2883,14 +2883,14 @@
     bool wasInLoop = _inLoop;
     _inLoop = true;
     try {
-      Token awaitKeyword = null;
+      Token awaitKeyword;
       if (_matchesKeyword(Keyword.AWAIT)) {
         awaitKeyword = getAndAdvance();
       }
       Token forKeyword = _expectKeyword(Keyword.FOR);
       Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
-      VariableDeclarationList variableList = null;
-      Expression initialization = null;
+      VariableDeclarationList variableList;
+      Expression initialization;
       if (!_matches(TokenType.SEMICOLON)) {
         CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
         if (_matchesIdentifier() &&
@@ -2915,8 +2915,8 @@
           if (type == TokenType.COLON) {
             _reportErrorForCurrentToken(ParserErrorCode.COLON_IN_PLACE_OF_IN);
           }
-          DeclaredIdentifier loopVariable = null;
-          SimpleIdentifier identifier = null;
+          DeclaredIdentifier loopVariable;
+          SimpleIdentifier identifier;
           if (variableList == null) {
             // We found: <expression> 'in'
             _reportErrorForCurrentToken(
@@ -2981,12 +2981,12 @@
             ParserErrorCode.INVALID_AWAIT_IN_FOR, awaitKeyword);
       }
       Token leftSeparator = _expect(TokenType.SEMICOLON);
-      Expression condition = null;
+      Expression condition;
       if (!_matches(TokenType.SEMICOLON)) {
         condition = parseExpression2();
       }
       Token rightSeparator = _expect(TokenType.SEMICOLON);
-      List<Expression> updaters = null;
+      List<Expression> updaters;
       if (!_matches(TokenType.CLOSE_PAREN)) {
         updaters = parseExpressionList();
       }
@@ -3051,8 +3051,8 @@
         }
         return astFactory.emptyFunctionBody(getAndAdvance());
       }
-      Token keyword = null;
-      Token star = null;
+      Token keyword;
+      Token star;
       bool foundAsync = false;
       bool foundSync = false;
       if (type.isKeyword) {
@@ -3080,7 +3080,7 @@
         if (keyword != null) {
           if (!foundAsync) {
             _reportErrorForToken(ParserErrorCode.INVALID_SYNC, keyword);
-            keyword = null;
+            keyword;
           } else if (star != null) {
             _reportErrorForToken(
                 ParserErrorCode.INVALID_STAR_AFTER_ASYNC, star);
@@ -3093,7 +3093,7 @@
           _advance();
         }
         Expression expression = parseExpression2();
-        Token semicolon = null;
+        Token semicolon;
         if (!inExpression) {
           semicolon = _expect(TokenType.SEMICOLON);
         }
@@ -3118,7 +3118,7 @@
         return astFactory.blockFunctionBody(keyword, star, parseBlock());
       } else if (_matchesKeyword(Keyword.NATIVE)) {
         Token nativeToken = getAndAdvance();
-        StringLiteral stringLiteral = null;
+        StringLiteral stringLiteral;
         if (_matches(TokenType.STRING)) {
           stringLiteral = _parseStringLiteralUnchecked();
         }
@@ -3153,10 +3153,10 @@
       CommentAndMetadata commentAndMetadata,
       Token externalKeyword,
       TypeAnnotation returnType) {
-    Token keywordToken = null;
+    Token keywordToken;
     bool isGetter = false;
     Keyword keyword = _currentToken.keyword;
-    SimpleIdentifier name = null;
+    SimpleIdentifier name;
     if (keyword == Keyword.GET) {
       keywordToken = getAndAdvance();
       isGetter = true;
@@ -3165,13 +3165,13 @@
     }
     if (keywordToken != null && _matches(TokenType.OPEN_PAREN)) {
       name = astFactory.simpleIdentifier(keywordToken, isDeclaration: true);
-      keywordToken = null;
+      keywordToken;
       isGetter = false;
     } else {
       name = parseSimpleIdentifier(isDeclaration: true);
     }
     TypeParameterList typeParameters = _parseGenericMethodTypeParameters();
-    FormalParameterList parameters = null;
+    FormalParameterList parameters;
     if (!isGetter) {
       if (_matches(TokenType.OPEN_PAREN)) {
         parameters = _parseFormalParameterListUnchecked();
@@ -3261,7 +3261,7 @@
   ///         type identifier
   GenericFunctionType parseGenericFunctionTypeAfterReturnType(
       TypeAnnotation returnType) {
-    Token functionKeyword = null;
+    Token functionKeyword;
     if (_matchesKeyword(Keyword.FUNCTION)) {
       functionKeyword = getAndAdvance();
     } else if (_matchesIdentifier()) {
@@ -3269,7 +3269,7 @@
     } else {
       _reportErrorForCurrentToken(ParserErrorCode.MISSING_FUNCTION_KEYWORD);
     }
-    TypeParameterList typeParameters = null;
+    TypeParameterList typeParameters;
     if (_matches(TokenType.LT)) {
       typeParameters = parseTypeParameterList();
     }
@@ -3288,7 +3288,7 @@
   GenericTypeAlias parseGenericTypeAlias(
       CommentAndMetadata commentAndMetadata, Token keyword) {
     Identifier name = _parseSimpleIdentifierUnchecked(isDeclaration: true);
-    TypeParameterList typeParameters = null;
+    TypeParameterList typeParameters;
     if (_matches(TokenType.LT)) {
       typeParameters = parseTypeParameterList();
     }
@@ -3406,8 +3406,8 @@
     Expression condition = parseExpression2();
     Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
     Statement thenStatement = parseStatement2();
-    Token elseKeyword = null;
-    Statement elseStatement = null;
+    Token elseKeyword;
+    Statement elseStatement;
     if (_matchesKeyword(Keyword.ELSE)) {
       elseKeyword = getAndAdvance();
       elseStatement = parseStatement2();
@@ -3444,9 +3444,9 @@
     Token importKeyword = getAndAdvance();
     StringLiteral libraryUri = _parseUri();
     List<Configuration> configurations = _parseConfigurations();
-    Token deferredToken = null;
-    Token asToken = null;
-    SimpleIdentifier prefix = null;
+    Token deferredToken;
+    Token asToken;
+    SimpleIdentifier prefix;
     if (_matchesKeyword(Keyword.DEFERRED)) {
       deferredToken = getAndAdvance();
     }
@@ -4102,8 +4102,8 @@
     }
     FinalConstVarOrType holder = parseFinalConstVarOrType(!inFunctionType,
         inFunctionType: inFunctionType);
-    Token thisKeyword = null;
-    Token period = null;
+    Token thisKeyword;
+    Token period;
     if (_matchesKeyword(Keyword.THIS)) {
       thisKeyword = getAndAdvance();
       period = _expect(TokenType.PERIOD);
@@ -4339,7 +4339,7 @@
       return parseStringLiteral();
     } else if (type == TokenType.INT) {
       Token token = getAndAdvance();
-      int value = null;
+      int value;
       try {
         value = int.parse(token.lexeme);
       } on FormatException {
@@ -4374,7 +4374,7 @@
       return astFactory.doubleLiteral(token, value);
     } else if (type == TokenType.HEXADECIMAL) {
       Token token = getAndAdvance();
-      int value = null;
+      int value;
       try {
         value = int.parse(token.lexeme);
       } on FormatException {
@@ -4443,8 +4443,8 @@
   RedirectingConstructorInvocation parseRedirectingConstructorInvocation(
       bool hasPeriod) {
     Token keyword = getAndAdvance();
-    Token period = null;
-    SimpleIdentifier constructorName = null;
+    Token period;
+    SimpleIdentifier constructorName;
     if (hasPeriod) {
       period = getAndAdvance();
       if (_matchesIdentifier()) {
@@ -4482,7 +4482,7 @@
           expression, asOperator, parseTypeNotVoid(true));
     } else if (keyword == Keyword.IS) {
       Token isOperator = getAndAdvance();
-      Token notOperator = null;
+      Token notOperator;
       if (_matches(TokenType.BANG)) {
         notOperator = getAndAdvance();
       }
@@ -4614,7 +4614,7 @@
     }
     _treeDepth++;
     try {
-      List<Label> labels = null;
+      List<Label> labels;
       while (
           _matchesIdentifier() && _currentToken.next.type == TokenType.COLON) {
         Label label = parseLabel(isDeclaration: true);
@@ -4664,8 +4664,8 @@
   ///         'super' ('.' identifier)? arguments
   SuperConstructorInvocation parseSuperConstructorInvocation() {
     Token keyword = getAndAdvance();
-    Token period = null;
-    SimpleIdentifier constructorName = null;
+    Token period;
+    SimpleIdentifier constructorName;
     if (_matches(TokenType.PERIOD)) {
       period = getAndAdvance();
       constructorName = parseSimpleIdentifier();
@@ -4695,7 +4695,7 @@
       Expression expression = parseExpression2();
       Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
       Token leftBracket = _expect(TokenType.OPEN_CURLY_BRACKET);
-      Token defaultKeyword = null;
+      Token defaultKeyword;
       List<SwitchMember> members = <SwitchMember>[];
       TokenType type = _currentToken.type;
       while (type != TokenType.EOF && type != TokenType.CLOSE_CURLY_BRACKET) {
@@ -4852,20 +4852,20 @@
     Token tryKeyword = getAndAdvance();
     Block body = _parseBlockChecked();
     List<CatchClause> catchClauses = <CatchClause>[];
-    Block finallyClause = null;
+    Block finallyClause;
     while (_matchesKeyword(Keyword.ON) || _matchesKeyword(Keyword.CATCH)) {
-      Token onKeyword = null;
-      TypeName exceptionType = null;
+      Token onKeyword;
+      TypeName exceptionType;
       if (_matchesKeyword(Keyword.ON)) {
         onKeyword = getAndAdvance();
         exceptionType = parseTypeNotVoid(false);
       }
-      Token catchKeyword = null;
-      Token leftParenthesis = null;
-      SimpleIdentifier exceptionParameter = null;
-      Token comma = null;
-      SimpleIdentifier stackTraceParameter = null;
-      Token rightParenthesis = null;
+      Token catchKeyword;
+      Token leftParenthesis;
+      SimpleIdentifier exceptionParameter;
+      Token comma;
+      SimpleIdentifier stackTraceParameter;
+      Token rightParenthesis;
       if (_matchesKeyword(Keyword.CATCH)) {
         catchKeyword = getAndAdvance();
         leftParenthesis = _expect(TokenType.OPEN_PAREN);
@@ -4888,7 +4888,7 @@
           rightParenthesis,
           catchBody));
     }
-    Token finallyKeyword = null;
+    Token finallyKeyword;
     if (_matchesKeyword(Keyword.FINALLY)) {
       finallyKeyword = getAndAdvance();
       finallyClause = _parseBlockChecked();
@@ -4942,7 +4942,7 @@
   ///         typeWithoutFunction
   ///       | functionType
   TypeAnnotation parseTypeAnnotation(bool inExpression) {
-    TypeAnnotation type = null;
+    TypeAnnotation type;
     if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
       // Generic function type with no return type.
       type = parseGenericFunctionTypeAfterReturnType(null);
@@ -4994,7 +4994,7 @@
   ///         functionType
   ///       | typeNotVoidWithoutFunction
   TypeAnnotation parseTypeNotVoid(bool inExpression) {
-    TypeAnnotation type = null;
+    TypeAnnotation type;
     if (_atGenericFunctionTypeAfterReturnType(_currentToken)) {
       // Generic function type with no return type.
       type = parseGenericFunctionTypeAfterReturnType(null);
@@ -5150,8 +5150,8 @@
     // user is in the middle of inserting "int bar;" prior to
     // "@deprecated foo() {}").
     SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
-    Token equals = null;
-    Expression initializer = null;
+    Token equals;
+    Expression initializer;
     if (_matches(TokenType.EQ)) {
       equals = getAndAdvance();
       initializer = parseExpression2();
@@ -5268,7 +5268,7 @@
   ///         'yield' '*'? expression ';'
   YieldStatement parseYieldStatement() {
     Token yieldToken = getAndAdvance();
-    Token star = null;
+    Token star;
     if (_matches(TokenType.STAR)) {
       star = getAndAdvance();
     }
@@ -5390,7 +5390,7 @@
   ///
   /// This method must be kept in sync with [parseTypeAnnotation].
   Token skipTypeAnnotation(Token startToken) {
-    Token next = null;
+    Token next;
     if (_atGenericFunctionTypeAfterReturnType(startToken)) {
       // Generic function type with no return type.
       next = skipGenericFunctionTypeAfterReturnType(startToken);
@@ -6053,7 +6053,7 @@
     if (_matches(TokenType.COMMA)) {
       comma = getAndAdvance();
       if (_matches(TokenType.CLOSE_PAREN)) {
-        comma = null;
+        comma;
       } else {
         message = parseExpression2();
         if (_matches(TokenType.COMMA)) {
@@ -6142,14 +6142,14 @@
       TypeParameterList typeParameters) {
     Token equals = _expect(TokenType.EQ);
     TypeName superclass = parseTypeName(false);
-    WithClause withClause = null;
+    WithClause withClause;
     if (_matchesKeyword(Keyword.WITH)) {
       withClause = parseWithClause();
     } else {
       _reportErrorForCurrentToken(
           ParserErrorCode.EXPECTED_TOKEN, [Keyword.WITH.lexeme]);
     }
-    ImplementsClause implementsClause = null;
+    ImplementsClause implementsClause;
     if (_matchesKeyword(Keyword.IMPLEMENTS)) {
       implementsClause = parseImplementsClause();
     }
@@ -6186,7 +6186,7 @@
   /// Parse a list of configurations. Return the configurations that were
   /// parsed, or `null` if there are no configurations.
   List<Configuration> _parseConfigurations() {
-    List<Configuration> configurations = null;
+    List<Configuration> configurations;
     while (_matchesKeyword(Keyword.IF)) {
       configurations ??= <Configuration>[];
       configurations.add(parseConfiguration());
@@ -6204,8 +6204,8 @@
       SimpleIdentifier name,
       FormalParameterList parameters) {
     bool bodyAllowed = externalKeyword == null;
-    Token separator = null;
-    List<ConstructorInitializer> initializers = null;
+    Token separator;
+    List<ConstructorInitializer> initializers;
     if (_matches(TokenType.COLON)) {
       separator = getAndAdvance();
       initializers = <ConstructorInitializer>[];
@@ -6239,7 +6239,7 @@
             ParserErrorCode.FACTORY_WITH_INITIALIZERS, factoryKeyword);
       }
     }
-    ConstructorName redirectedConstructor = null;
+    ConstructorName redirectedConstructor;
     FunctionBody body;
     if (_matches(TokenType.EQ)) {
       separator = getAndAdvance();
@@ -6333,17 +6333,17 @@
     // better.
     //
     List<FormalParameter> parameters = <FormalParameter>[];
-    Token leftSquareBracket = null;
-    Token rightSquareBracket = null;
-    Token leftCurlyBracket = null;
-    Token rightCurlyBracket = null;
+    Token leftSquareBracket;
+    Token rightSquareBracket;
+    Token leftCurlyBracket;
+    Token rightCurlyBracket;
     ParameterKind kind = ParameterKind.REQUIRED;
     bool firstParameter = true;
     bool reportedMultiplePositionalGroups = false;
     bool reportedMultipleNamedGroups = false;
     bool reportedMixedGroups = false;
     bool wasOptionalParameter = false;
-    Token initialToken = null;
+    Token initialToken;
     do {
       if (firstParameter) {
         firstParameter = false;
@@ -6430,7 +6430,7 @@
                 ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
                 ['}', ']']);
             rightCurlyBracket = rightSquareBracket;
-            rightSquareBracket = null;
+            rightSquareBracket;
             // Skip over synthetic closer inserted by fasta
             // since we've already reported an error
             if (_currentToken.type == TokenType.CLOSE_CURLY_BRACKET &&
@@ -6452,7 +6452,7 @@
                 ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
                 [']', '}']);
             rightSquareBracket = rightCurlyBracket;
-            rightCurlyBracket = null;
+            rightCurlyBracket;
             // Skip over synthetic closer inserted by fasta
             // since we've already reported an error
             if (_currentToken.type == TokenType.CLOSE_SQUARE_BRACKET &&
@@ -6535,12 +6535,12 @@
   ///         returnType? name
   FunctionTypeAlias _parseFunctionTypeAlias(
       CommentAndMetadata commentAndMetadata, Token keyword) {
-    TypeAnnotation returnType = null;
+    TypeAnnotation returnType;
     if (hasReturnTypeInTypeAlias) {
       returnType = parseTypeAnnotation(false);
     }
     SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
-    TypeParameterList typeParameters = null;
+    TypeParameterList typeParameters;
     if (_matches(TokenType.LT)) {
       typeParameters = parseTypeParameterList();
     }
@@ -6989,7 +6989,7 @@
         }
       } else {
         Token openToken = getAndAdvance();
-        Expression expression = null;
+        Expression expression;
         if (_matchesKeyword(Keyword.THIS)) {
           expression = astFactory.thisExpression(getAndAdvance());
         } else {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 16c150d..1a6ab3f 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1864,7 +1864,7 @@
   /// Return `true` if the given [expression] is resolved to a constant
   /// variable.
   bool _isDebugConstant(Expression expression) {
-    Element element = null;
+    Element element;
     if (expression is Identifier) {
       element = expression.staticElement;
     } else if (expression is PropertyAccess) {
@@ -3044,22 +3044,22 @@
 
   /// The class declaration representing the class containing the current node,
   /// or `null` if the current node is not contained in a class.
-  ClassDeclaration _enclosingClassDeclaration = null;
+  ClassDeclaration _enclosingClassDeclaration;
 
   /// The function type alias representing the function type containing the
   /// current node, or `null` if the current node is not contained in a function
   /// type alias.
-  FunctionTypeAlias _enclosingFunctionTypeAlias = null;
+  FunctionTypeAlias _enclosingFunctionTypeAlias;
 
   /// The element representing the function containing the current node, or
   /// `null` if the current node is not contained in a function.
-  ExecutableElement _enclosingFunction = null;
+  ExecutableElement _enclosingFunction;
 
   /// The mixin declaration representing the class containing the current node,
   /// or `null` if the current node is not contained in a mixin.
-  MixinDeclaration _enclosingMixinDeclaration = null;
+  MixinDeclaration _enclosingMixinDeclaration;
 
-  InferenceContext inferenceContext = null;
+  InferenceContext inferenceContext;
 
   /// The object keeping track of which elements have had their types promoted.
   TypePromotionManager _promoteManager;
@@ -3171,7 +3171,7 @@
     }
   }
 
-  NullabilitySuffix get _noneOrStarSuffix {
+  NullabilitySuffix get noneOrStarSuffix {
     return _nonNullableEnabled
         ? NullabilitySuffix.none
         : NullabilitySuffix.star;
@@ -3189,7 +3189,7 @@
   /// @param expression the expression with which the element is associated
   /// @return the element associated with the given expression
   VariableElement getOverridableStaticElement(Expression expression) {
-    Element element = null;
+    Element element;
     if (expression is SimpleIdentifier) {
       element = expression.staticElement;
     } else if (expression is PrefixedIdentifier) {
@@ -3241,7 +3241,7 @@
     // parameter and return type are in terms of the surrounding context.
     return fnType.instantiate(typeParameters.map((TypeParameter t) {
       return t.declaredElement.instantiate(
-        nullabilitySuffix: _noneOrStarSuffix,
+        nullabilitySuffix: noneOrStarSuffix,
       );
     }).toList());
   }
@@ -4312,9 +4312,9 @@
     // because it needs to be visited in the context of the constructor
     // invocation.
     //
+    node.accept(elementResolver);
     InferenceContext.setType(node.argumentList, node.staticElement?.type);
     node.argumentList?.accept(this);
-    node.accept(elementResolver);
     node.accept(typeAnalyzer);
   }
 
@@ -4419,9 +4419,9 @@
     // because it needs to be visited in the context of the constructor
     // invocation.
     //
+    node.accept(elementResolver);
     InferenceContext.setType(node.argumentList, node.staticElement?.type);
     node.argumentList?.accept(this);
-    node.accept(elementResolver);
     node.accept(typeAnalyzer);
   }
 
@@ -4994,7 +4994,7 @@
     int requiredParameterCount = 0;
     int unnamedParameterCount = 0;
     List<ParameterElement> unnamedParameters = new List<ParameterElement>();
-    Map<String, ParameterElement> namedParameters = null;
+    Map<String, ParameterElement> namedParameters;
     int length = parameters.length;
     for (int i = 0; i < length; i++) {
       ParameterElement parameter = parameters[i];
@@ -5016,7 +5016,7 @@
     List<ParameterElement> resolvedParameters =
         new List<ParameterElement>(argumentCount);
     int positionalArgumentCount = 0;
-    HashSet<String> usedNames = null;
+    HashSet<String> usedNames;
     bool noBlankArguments = true;
     for (int i = 0; i < argumentCount; i++) {
       Expression argument = arguments[i];
@@ -6124,7 +6124,7 @@
       return;
     }
 
-    DartType type = null;
+    DartType type;
     if (element == DynamicElementImpl.instance) {
       _setElement(typeName, element);
       type = DynamicTypeImpl.instance;
@@ -6548,8 +6548,8 @@
   final Source source;
   final AnalysisErrorListener errorListener;
 
-  Scope libraryScope = null;
-  TypeNameResolver typeNameResolver = null;
+  Scope libraryScope;
+  TypeNameResolver typeNameResolver;
 
   TypeParameterBoundsResolver(this.typeSystem, this.library, this.source,
       this.errorListener, FeatureSet featureSet)
@@ -6636,7 +6636,7 @@
   void _resolveTypeParameters(
       TypeParameterList typeParameters, Scope createTypeParametersScope()) {
     if (typeParameters != null) {
-      Scope typeParametersScope = null;
+      Scope typeParametersScope;
       for (TypeParameter typeParameter in typeParameters.typeParameters) {
         TypeAnnotation bound = typeParameter.bound;
         if (bound != null) {
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 67dfd49..f981dcf 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -367,7 +367,7 @@
 
   @override
   void visitMapLiteralEntry(MapLiteralEntry node) {
-    String libraryName = null;
+    String libraryName;
     Expression key = node.key;
     if (key is SimpleStringLiteral) {
       libraryName = "$_LIBRARY_PREFIX${key.value}";
@@ -486,7 +486,7 @@
    * 'lib' directory within the SDK.
    */
   @override
-  String path = null;
+  String path;
 
   /**
    * The name of the category containing the library. Unless otherwise specified
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index e8108bb..5d44d4b 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -107,9 +107,21 @@
    * inferred type parameters found by the resolver.
    */
   void inferConstructorName(ConstructorName node, InterfaceType type) {
+    // TODO(scheglov) Inline.
     node.type.type = type;
-    if (type != _typeSystem.instantiateToBounds(type.element.type)) {
-      _resolver.inferenceContext.recordInference(node.parent, type);
+    // TODO(scheglov) Remove when DDC stops using analyzer.
+    var element = type.element;
+    if (element.typeParameters.isNotEmpty) {
+      var typeParameterBounds = _typeSystem.instantiateTypeFormalsToBounds(
+        element.typeParameters,
+      );
+      var instantiatedToBounds = element.instantiate(
+        typeArguments: typeParameterBounds,
+        nullabilitySuffix: _noneOrStarSuffix,
+      );
+      if (type != instantiatedToBounds) {
+        _resolver.inferenceContext.recordInference(node.parent, type);
+      }
     }
   }
 
@@ -1389,13 +1401,13 @@
       }
       ClassElement returnType = library.getType(elementName);
       if (returnType != null) {
-        if (returnType.typeParameters.isNotEmpty) {
-          // Caller can't deal with unbound type parameters, so substitute
-          // `dynamic`.
-          return returnType.type.instantiate(
-              returnType.typeParameters.map((_) => _dynamicType).toList());
-        }
-        return returnType.type;
+        return returnType.instantiate(
+          typeArguments: List.filled(
+            returnType.typeParameters.length,
+            _dynamicType,
+          ),
+          nullabilitySuffix: _noneOrStarSuffix,
+        );
       }
     }
     return null;
@@ -1802,7 +1814,7 @@
         e.library.source.uri.toString() == 'dart:_foreign_helper' &&
         e.name == 'JS') {
       String typeStr = _getFirstArgumentAsString(node.argumentList);
-      DartType returnType = null;
+      DartType returnType;
       if (typeStr == '-dynamic') {
         returnType = _typeProvider.bottomType;
       } else {
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
index f6687b4..810d916 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_test_factory.dart
@@ -1345,7 +1345,7 @@
           TokenFactory.tokenFromKeyword(Keyword.EXTENDS), bound);
 
   static TypeParameterList typeParameterList([List<String> typeNames]) {
-    List<TypeParameter> typeParameters = null;
+    List<TypeParameter> typeParameters;
     if (typeNames != null && typeNames.isNotEmpty) {
       typeParameters = new List<TypeParameter>();
       for (String typeName in typeNames) {
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 7a84adf..d64f2d5 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -361,7 +361,7 @@
     }
 
     List<TypeParameterElement> getFreeParameters(DartType rootType) {
-      List<TypeParameterElement> parameters = null;
+      List<TypeParameterElement> parameters;
       Set<DartType> visitedTypes = new HashSet<DartType>();
 
       void appendParameters(DartType type) {
@@ -1174,7 +1174,7 @@
   }
 
   static List<T> _transformList<T>(List<T> list, T f(T t)) {
-    List<T> newList = null;
+    List<T> newList;
     for (var i = 0; i < list.length; i++) {
       var item = list[i];
       var newItem = f(item);
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 52439ce..8217608 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -1266,8 +1266,8 @@
       }
     }
 
-    String docComplete = null;
-    String docSummary = null;
+    String docComplete;
+    String docSummary;
 
     void setDartDoc(AnnotatedNode node) {
       if (node.documentationComment != null) {
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index bb96dd0..ff48204 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -381,8 +381,14 @@
     _indexUnitDeclarations(unitContext, unitRef, unitNode);
   }
 
-  MethodElementImpl _method(ClassElementImpl enclosing, Reference reference) {
-    enclosing.methods;
+  MethodElementImpl _method(ElementImpl enclosing, Reference reference) {
+    if (enclosing is ClassElementImpl) {
+      enclosing.methods;
+    } else if (enclosing is ExtensionElementImpl) {
+      enclosing.methods;
+    } else {
+      throw StateError('${enclosing.runtimeType}');
+    }
     // Requesting methods sets elements for all of them.
     assert(reference.element != null);
     return reference.element;
diff --git a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
index ac7435a..5d77644 100644
--- a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
@@ -10,15 +10,18 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/summary2/ast_resolver.dart';
 import 'package:analyzer/src/summary2/link.dart';
+import 'package:analyzer/src/summary2/linking_node_scope.dart';
 
 class MetadataResolver extends ThrowingAstVisitor<void> {
   final Linker _linker;
   final LibraryElement _libraryElement;
   final Scope _libraryScope;
   final CompilationUnitElement _unitElement;
+  Scope _scope;
 
-  MetadataResolver(this._linker, this._libraryElement, this._libraryScope,
-      this._unitElement);
+  MetadataResolver(
+      this._linker, this._libraryElement, this._libraryScope, this._unitElement)
+      : _scope = _libraryScope;
 
   @override
   void visitAnnotation(Annotation node) {
@@ -27,7 +30,7 @@
     var holder = ElementHolder();
     node.accept(LocalElementBuilder(holder, null));
 
-    var astResolver = AstResolver(_linker, _libraryElement, _libraryScope);
+    var astResolver = AstResolver(_linker, _libraryElement, _scope);
     astResolver.rewriteAst(node);
     astResolver.resolve(node);
   }
@@ -36,7 +39,13 @@
   void visitClassDeclaration(ClassDeclaration node) {
     node.metadata.accept(this);
     node.typeParameters?.accept(this);
-    node.members.accept(this);
+
+    _scope = LinkingNodeContext.get(node).scope;
+    try {
+      node.members.accept(this);
+    } finally {
+      _scope = _libraryScope;
+    }
   }
 
   @override
@@ -82,7 +91,13 @@
   void visitExtensionDeclaration(ExtensionDeclaration node) {
     node.metadata.accept(this);
     node.typeParameters?.accept(this);
-    node.members.accept(this);
+
+    _scope = LinkingNodeContext.get(node).scope;
+    try {
+      node.members.accept(this);
+    } finally {
+      _scope = _libraryScope;
+    }
   }
 
   @override
@@ -161,7 +176,13 @@
   void visitMixinDeclaration(MixinDeclaration node) {
     node.metadata.accept(this);
     node.typeParameters?.accept(this);
-    node.members.accept(this);
+
+    _scope = LinkingNodeContext.get(node).scope;
+    try {
+      node.members.accept(this);
+    } finally {
+      _scope = _libraryScope;
+    }
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 2cef609..76b23f9 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -94,9 +94,9 @@
         variable.initializer.accept(LocalElementBuilder(holder, null));
         (element as VariableElementImpl).encloseElements(holder.functions);
 
-        InferenceContext.setType(variable.initializer, typeNode.type);
         var astResolver = AstResolver(linker, _library, _scope);
         astResolver.rewriteAst(variable.initializer);
+        InferenceContext.setType(variable.initializer, typeNode.type);
         astResolver.resolve(variable.initializer);
       }
     }
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3a196922..0c0a8e6 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -1012,7 +1012,7 @@
 
     var type = functionType.returnType;
 
-    ClassElement expectedElement = null;
+    ClassElement expectedElement;
     if (body.isAsynchronous) {
       if (body.isGenerator) {
         // Stream<T> -> T
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index d0e19d8..a4707b5 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -147,7 +147,7 @@
    */
   DartType _computeParameterType(ParameterElement parameter, int index,
       List<FunctionType> overriddenTypes) {
-    DartType parameterType = null;
+    DartType parameterType;
     int length = overriddenTypes.length;
     for (int i = 0; i < length; i++) {
       ParameterElement matchingParameter = _getCorrespondingParameter(
@@ -191,7 +191,7 @@
    * want to be smarter about it.
    */
   DartType _computeReturnType(Iterable<DartType> overriddenReturnTypes) {
-    DartType returnType = null;
+    DartType returnType;
     for (DartType type in overriddenReturnTypes) {
       if (type == null) {
         type = typeProvider.dynamicType;
@@ -567,7 +567,7 @@
    * Initialize a newly created gatherer to gather all of the variables that
    * pass the given [filter] (or all variables if no filter is provided).
    */
-  VariableGatherer([this.filter = null]);
+  VariableGatherer([this.filter]);
 
   @override
   void visitSimpleIdentifier(SimpleIdentifier node) {
diff --git a/pkg/analyzer/lib/src/test_utilities/find_node.dart b/pkg/analyzer/lib/src/test_utilities/find_node.dart
index 7e9a9ed..87a5af6 100644
--- a/pkg/analyzer/lib/src/test_utilities/find_node.dart
+++ b/pkg/analyzer/lib/src/test_utilities/find_node.dart
@@ -35,6 +35,10 @@
     return _node(search, (n) => n is Block);
   }
 
+  BooleanLiteral booleanLiteral(String search) {
+    return _node(search, (n) => n is BooleanLiteral);
+  }
+
   BreakStatement breakStatement(String search) {
     return _node(search, (n) => n is BreakStatement);
   }
@@ -75,6 +79,10 @@
     return _node(search, (n) => n is DoStatement);
   }
 
+  DoubleLiteral doubleLiteral(String search) {
+    return _node(search, (n) => n is DoubleLiteral);
+  }
+
   ExportDirective export(String search) {
     return _node(search, (n) => n is ExportDirective);
   }
@@ -179,6 +187,10 @@
     return _node(search, (n) => n is NamedExpression);
   }
 
+  NullLiteral nullLiteral(String search) {
+    return _node(search, (n) => n is NullLiteral);
+  }
+
   ParenthesizedExpression parenthesized(String search) {
     return _node(search, (n) => n is ParenthesizedExpression);
   }
@@ -239,6 +251,10 @@
     return _node(search, (n) => n is SwitchStatement);
   }
 
+  SymbolLiteral symbolLiteral(String search) {
+    return _node(search, (n) => n is SymbolLiteral);
+  }
+
   ThisExpression this_(String search) {
     return _node(search, (n) => n is ThisExpression);
   }
@@ -290,7 +306,7 @@
 
   AstNode _node(String search, bool Function(AstNode) predicate) {
     var index = content.indexOf(search);
-    if (content.indexOf(search, index + 1) != -1) {
+    if (content.contains(search, index + 1)) {
       throw new StateError('The pattern |$search| is not unique in:\n$content');
     }
     if (index < 0) {
diff --git a/pkg/analyzer/lib/src/util/glob.dart b/pkg/analyzer/lib/src/util/glob.dart
index 97c122f..0283753 100644
--- a/pkg/analyzer/lib/src/util/glob.dart
+++ b/pkg/analyzer/lib/src/util/glob.dart
@@ -81,8 +81,8 @@
   static bool _hasJustPrefix(String pattern, String prefix) {
     if (pattern.startsWith(prefix)) {
       int prefixLength = prefix.length;
-      return pattern.indexOf('*', prefixLength) == -1 &&
-          pattern.indexOf('?', prefixLength) == -1;
+      return !pattern.contains('*', prefixLength) &&
+          !pattern.contains('?', prefixLength);
     }
     return false;
   }
diff --git a/pkg/analyzer/lib/src/workspace/bazel.dart b/pkg/analyzer/lib/src/workspace/bazel.dart
index d66c851..5fcbbaf 100644
--- a/pkg/analyzer/lib/src/workspace/bazel.dart
+++ b/pkg/analyzer/lib/src/workspace/bazel.dart
@@ -80,7 +80,7 @@
       String fileUriPart = uriPath.substring(slash + 1);
       String filePath = fileUriPart.replaceAll('/', _context.separator);
 
-      if (packageName.indexOf('.') == -1) {
+      if (!packageName.contains('.')) {
         String fullFilePath = _context.join(_workspace.root, 'third_party',
             'dart', packageName, 'lib', filePath);
         File file = _workspace.findFile(fullFilePath);
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 4a90853..db57bbb 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -165,6 +165,10 @@
 var v = const A(foo);
 ''', [
       error(StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 116, 3),
+      error(
+          CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
+          116,
+          3),
     ]);
   }
 
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index 6a4c187..8f4902a7 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -588,7 +588,7 @@
 
   test_visitConstructorName_unnamed() async {
     ClassElementImpl classA = ElementFactory.classElement2("A");
-    String constructorName = null;
+    String constructorName;
     ConstructorElement constructor =
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
@@ -738,7 +738,7 @@
 
   test_visitInstanceCreationExpression_unnamed() async {
     ClassElementImpl classA = ElementFactory.classElement2("A");
-    String constructorName = null;
+    String constructorName;
     ConstructorElement constructor =
         ElementFactory.constructorElement2(classA, constructorName);
     classA.constructors = <ConstructorElement>[constructor];
@@ -754,7 +754,7 @@
 
   test_visitInstanceCreationExpression_unnamed_namedParameter() async {
     ClassElementImpl classA = ElementFactory.classElement2("A");
-    String constructorName = null;
+    String constructorName;
     ConstructorElementImpl constructor =
         ElementFactory.constructorElement2(classA, constructorName);
     String parameterName = "a";
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index fc6c5d50c..d3e8852 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -2,13 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'resolver_test_case.dart';
+import '../src/dart/resolution/driver_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -17,221 +14,203 @@
 }
 
 @reflectiveTest
-class ErrorSuppressionTest extends ResolverTestCase {
+class ErrorSuppressionTest extends DriverResolutionTest {
   String get ignoredCode => 'const_initialized_with_non_constant_value';
 
-  List<ErrorCode> get reportedCodes => [
-        CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
-      ];
-
-  List<ErrorCode> get reportedCodesWithAssignment => [
-        StaticTypeWarningCode.INVALID_ASSIGNMENT,
-        CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE,
-      ];
-
   test_error_code_mismatch() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 // ignore: $ignoredCode
 int x = '';
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 61, 2),
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 75,
+          1),
+    ]);
   }
 
   test_ignore_first() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 // ignore: invalid_assignment
 int x = '';
 // ... but no ignore here ...
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodes);
+''', [
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 82,
+          1),
+    ]);
   }
 
   test_ignore_first_trailing() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 int x = ''; // ignore: invalid_assignment
 // ... but no ignore here ...
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodes);
+''', [
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 82,
+          1),
+    ]);
   }
 
   test_ignore_for_file() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 int x = '';  //INVALID_ASSIGNMENT
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 // ignore_for_file: invalid_assignment
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodes);
+''', [
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 44,
+          1),
+    ]);
   }
 
   test_ignore_for_file_whitespace_variant() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 //ignore_for_file:   $ignoredCode , invalid_assignment
 int x = '';  //INVALID_ASSIGNMENT
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_ignore_only_trailing() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = ''; // ignore: invalid_assignment
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_ignore_second() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 //INVALID_ASSIGNMENT
 int x = '';
 // ignore: $ignoredCode
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 29, 2),
+    ]);
   }
 
   test_ignore_second_trailing() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 //INVALID_ASSIGNMENT
 int x = '';
 const y = x; // ignore: $ignoredCode
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 29, 2),
+    ]);
   }
 
   test_ignore_upper_case() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = ''; // ignore: INVALID_ASSIGNMENT
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_invalid_error_code() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 // ignore: right_format_wrong_code
 int x = '';
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 43, 2),
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 57,
+          1),
+    ]);
   }
 
   test_missing_error_codes() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
     int x = 3;
 // ignore:
 const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
+''', [
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 43,
+          1),
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 43, 1),
+    ]);
   }
 
   test_missing_metadata_suffix() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 // ignore invalid_assignment
 String y = 3; //INVALID_ASSIGNMENT
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 40, 1),
+    ]);
   }
 
   test_multiple_comments() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 int x = ''; //This is the first comment...
 // ignore: $ignoredCode
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
+    ]);
   }
 
   test_multiple_ignore_for_files() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = '';  //INVALID_ASSIGNMENT
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 // ignore_for_file: invalid_assignment,$ignoredCode
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_multiple_ignores() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = 3;
 // ignore: invalid_assignment, $ignoredCode
 const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_multiple_ignores_trailing() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = 3;
 const String y = x; // ignore: invalid_assignment, $ignoredCode
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_multiple_ignores_whitespace_variant_1() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = 3;
 //ignore:invalid_assignment,$ignoredCode
 const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_multiple_ignores_whitespace_variant_2() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = 3;
 //ignore: invalid_assignment,$ignoredCode
 const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_multiple_ignores_whitespace_variant_3() async {
-    Source source = addSource('''
+    await assertNoErrorsInCode('''
 int x = 3;
 // ignore: invalid_assignment,$ignoredCode
 const String y = x; //INVALID_ASSIGNMENT, CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
 ''');
-    await computeAnalysisResult(source);
-    assertErrors(source, []);
   }
 
   test_no_ignores() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 int x = '';  //INVALID_ASSIGNMENT
 const y = x; //CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, reportedCodesWithAssignment);
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 8, 2),
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 44,
+          1),
+    ]);
   }
 
   test_trailing_not_above() async {
-    Source source = addSource('''
+    await assertErrorsInCode('''
 int x = ''; // ignore: invalid_assignment
 int y = '';
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      StaticTypeWarningCode.INVALID_ASSIGNMENT,
+''', [
+      error(StaticTypeWarningCode.INVALID_ASSIGNMENT, 50, 2),
     ]);
   }
 }
diff --git a/pkg/analyzer/test/generated/invalid_code_test.dart b/pkg/analyzer/test/generated/invalid_code_test.dart
index e97dbde..f5d274f 100644
--- a/pkg/analyzer/test/generated/invalid_code_test.dart
+++ b/pkg/analyzer/test/generated/invalid_code_test.dart
@@ -166,6 +166,29 @@
 ''');
   }
 
+  test_fuzz_15() async {
+    // `@A` is not a valid annotation, it is missing arguments.
+    // There was a bug that we did not check for arguments being missing.
+    await _assertCanBeAnalyzed(r'''
+class A<T> {}
+
+@A
+class B {}
+''');
+  }
+
+  test_fuzz_16() async {
+    // The default constructor of `A` does not have formal parameters.
+    // But we give it arguments.
+    // There was a bug that we did not check for this mismatch.
+    await _assertCanBeAnalyzed(r'''
+class A<T> {}
+
+@A(0)
+class B {}
+''');
+  }
+
   test_fuzz_38091() async {
     // https://github.com/dart-lang/sdk/issues/38091
     // this caused an infinite loop in parser recovery
diff --git a/pkg/analyzer/test/generated/issues_test.dart b/pkg/analyzer/test/generated/issues_test.dart
index 93b97b9..198943b 100644
--- a/pkg/analyzer/test/generated/issues_test.dart
+++ b/pkg/analyzer/test/generated/issues_test.dart
@@ -16,6 +16,26 @@
 /// not obvious where to put the test otherwise.
 @reflectiveTest
 class IssuesTest extends DriverResolutionTest {
+  /// https://github.com/dart-lang/sdk/issues/38565
+  ///
+  /// The issue was that type inference for annotation instantiation
+  /// was done incorrectly, without resolving arguments to the annotation
+  /// constructor. So, we were trying to perform type inference using null
+  /// types of arguments.
+  test_issue38565() async {
+    await resolveTestCode('''
+class A<T> {
+  const A(int a);
+}
+
+class C {
+  @A(0)
+  int field;
+}
+''');
+    // Should not crash.
+  }
+
   /// https://github.com/dart-lang/sdk/issues/38589
   test_issue38589() async {
     await resolveTestCode('''
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index b219c94..75f8910 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -3,11 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/source_io.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../src/dart/resolution/driver_resolution.dart';
-import 'resolver_test_case.dart';
+import 'test_support.dart';
 
 main() {
   defineReflectiveSuite(() {
@@ -190,22 +189,24 @@
   }
 }
 
-class PubSuggestionCodeTest extends ResolverTestCase {
+class PubSuggestionCodeTest extends DriverResolutionTest {
   // TODO(brianwilkerson) The tests in this class are not being run, and all but
   //  the first would fail. We should implement these checks and enable the
   //  tests.
   test_import_package() async {
     await assertErrorsInCode('''
 import 'package:somepackage/other.dart';
-''', [CompileTimeErrorCode.URI_DOES_NOT_EXIST]);
+''', [
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 0, 0),
+    ]);
   }
 
   test_import_packageWithDotDot() async {
     await assertErrorsInCode('''
 import 'package:somepackage/../other.dart';
 ''', [
-      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-      HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 0, 0),
+      error(HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT, 0, 0),
     ]);
   }
 
@@ -213,71 +214,70 @@
     await assertErrorsInCode('''
 import 'package:../other.dart';
 ''', [
-      CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-      HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT
+      error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 0, 0),
+      error(HintCode.PACKAGE_IMPORT_CONTAINS_DOT_DOT, 0, 0),
     ]);
   }
 
   test_import_referenceIntoLibDirectory() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/lib/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE]);
+    newFile("/myproj/pubspec.yaml", content: "");
+    newFile("/myproj/lib/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/web/test.dart", "import '../lib/other.dart';", [
+      error(HintCode.FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE, 0, 0),
+    ]);
   }
 
   test_import_referenceIntoLibDirectory_no_pubspec() async {
-    addNamedSource("/myproj/lib/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/web/test.dart", "import '../lib/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    newFile("/myproj/lib/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/web/test.dart", "import '../lib/other.dart';", []);
   }
 
   test_import_referenceOutOfLibDirectory() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/web/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
-    await computeAnalysisResult(source);
-    assertErrors(
-        source, [HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE]);
+    newFile("/myproj/pubspec.yaml", content: "");
+    newFile("/myproj/web/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/lib/test.dart", "import '../web/other.dart';", [
+      error(HintCode.FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE, 0, 0),
+    ]);
   }
 
   test_import_referenceOutOfLibDirectory_no_pubspec() async {
-    addNamedSource("/myproj/web/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib/test.dart", "import '../web/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    newFile("/myproj/web/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/lib/test.dart", "import '../web/other.dart';", []);
   }
 
   test_import_valid_inside_lib1() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/lib/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib/test.dart", "import 'other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    newFile("/myproj/pubspec.yaml", content: "");
+    newFile("/myproj/lib/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/lib/test.dart", "import 'other.dart';", []);
   }
 
   test_import_valid_inside_lib2() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/lib/bar/other.dart", "");
-    Source source = addNamedSource(
-        "/myproj/lib/foo/test.dart", "import '../bar/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    newFile("/myproj/pubspec.yaml", content: "");
+    newFile("/myproj/lib/bar/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/lib/foo/test.dart", "import '../bar/other.dart';", []);
   }
 
   test_import_valid_outside_lib() async {
-    addNamedSource("/myproj/pubspec.yaml", "");
-    addNamedSource("/myproj/web/other.dart", "");
-    Source source =
-        addNamedSource("/myproj/lib2/test.dart", "import '../web/other.dart';");
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
+    newFile("/myproj/pubspec.yaml", content: "");
+    newFile("/myproj/web/other.dart", content: "");
+    await _assertErrorsInCodeInFile(
+        "/myproj/lib2/test.dart", "import '../web/other.dart';", []);
+  }
+
+  Future<void> _assertErrorsInCodeInFile(
+      String path, String content, List<ExpectedError> expectedErrors) async {
+    path = convertPath(path);
+    newFile(path, content: content);
+    result = await resolveFile(path);
+
+    var errorListener = new GatheringErrorListener();
+    errorListener.addAll(result.errors);
+    errorListener.assertErrors(expectedErrors);
   }
 }
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index c92e79d..11a75d9 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1681,6 +1681,34 @@
     expect(extension.members, hasLength(0));
   }
 
+  void test_constructor_named() {
+    var unit = parseCompilationUnit('''
+extension E on C {
+  E.named();
+}
+class C {}
+''', errors: [
+      expectedError(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 21, 1),
+    ]);
+    expect(unit.declarations, hasLength(2));
+    var extension = unit.declarations[0] as ExtensionDeclaration;
+    expect(extension.members, hasLength(0));
+  }
+
+  void test_constructor_unnamed() {
+    var unit = parseCompilationUnit('''
+extension E on C {
+  E();
+}
+class C {}
+''', errors: [
+      expectedError(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 21, 1),
+    ]);
+    expect(unit.declarations, hasLength(2));
+    var extension = unit.declarations[0] as ExtensionDeclaration;
+    expect(extension.members, hasLength(0));
+  }
+
   void test_missing_on() {
     var unit = parseCompilationUnit('extension E', errors: [
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 1),
@@ -1802,133 +1830,6 @@
   }
 }
 
-@reflectiveTest
-class VarianceParserTest_Fasta extends FastaParserTestCase {
-  @override
-  CompilationUnit parseCompilationUnit(String content,
-      {List<ErrorCode> codes,
-      List<ExpectedError> errors,
-      FeatureSet featureSet}) {
-    return super.parseCompilationUnit(content,
-        codes: codes,
-        errors: errors,
-        featureSet: featureSet ??
-            FeatureSet.forTesting(
-              sdkVersion: '2.5.0',
-              additionalFeatures: [Feature.variance],
-            ));
-  }
-
-  void test_class_enabled_single() {
-    var unit = parseCompilationUnit('class A<in T> { }');
-    expect(unit.declarations, hasLength(1));
-    var classDecl = unit.declarations[0] as ClassDeclaration;
-    expect(classDecl.name.name, 'A');
-    expect(classDecl.typeParameters.typeParameters, hasLength(1));
-    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
-  }
-
-  void test_class_enabled_multipleVariances() {
-    var unit = parseCompilationUnit('class A<in out inout T> { }', errors: [
-      expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 11, 3),
-      expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 15, 5)
-    ]);
-    expect(unit.declarations, hasLength(1));
-    var classDecl = unit.declarations[0] as ClassDeclaration;
-    expect(classDecl.name.name, 'A');
-    expect(classDecl.typeParameters.typeParameters, hasLength(1));
-    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
-  }
-
-  void test_class_disabled_single() {
-    parseCompilationUnit('class A<out T> { }',
-        errors: [
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_class_disabled_multiple() {
-    parseCompilationUnit('class A<in T, inout U, out V> { }',
-        errors: [
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 2),
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5),
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3)
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_mixin_enabled_single() {
-    var unit = parseCompilationUnit('mixin A<inout T> { }');
-    expect(unit.declarations, hasLength(1));
-    var mixinDecl = unit.declarations[0] as MixinDeclaration;
-    expect(mixinDecl.name.name, 'A');
-    expect(mixinDecl.typeParameters.typeParameters, hasLength(1));
-    expect(mixinDecl.typeParameters.typeParameters[0].name.name, 'T');
-  }
-
-  void test_mixin_disabled_single() {
-    parseCompilationUnit('mixin A<inout T> { }',
-        errors: [
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_mixin_disabled_multiple() {
-    parseCompilationUnit('mixin A<inout T, out U> { }',
-        errors: [
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
-          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_typedef_enabled() {
-    parseCompilationUnit('typedef A<inout X> = X Function(X);', errors: [
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
-    ]);
-  }
-
-  void test_typedef_disabled() {
-    parseCompilationUnit('typedef A<inout X> = X Function(X);',
-        errors: [
-          expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_list_enabled() {
-    parseCompilationUnit('List<out String> stringList = [];', errors: [
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
-    ]);
-  }
-
-  void test_list_disabled() {
-    parseCompilationUnit('List<out String> stringList = [];',
-        errors: [
-          expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-
-  void test_function_enabled() {
-    parseCompilationUnit('void A(in int value) {}', errors: [
-      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
-    ]);
-  }
-
-  void test_function_disabled() {
-    parseCompilationUnit('void A(in int value) {}',
-        errors: [
-          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
-          expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
-        ],
-        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
-  }
-}
-
 /**
  * Implementation of [AbstractParserTestCase] specialized for testing the
  * Fasta parser.
@@ -2959,6 +2860,21 @@
     parseCompilationUnit('f() { var x = g!.x + 7; }');
   }
 
+  void test_nullCheckBeforeIndex() {
+    // https://github.com/dart-lang/sdk/issues/37708
+    var unit = parseCompilationUnit('f() { foo.bar!.baz[arg]; }');
+    var funct = unit.declarations[0] as FunctionDeclaration;
+    var body = funct.functionExpression.body as BlockFunctionBody;
+    var statement = body.block.statements[0] as ExpressionStatement;
+    var expression = statement.expression as IndexExpression;
+    expect(expression.index.toSource(), 'arg');
+    var propertyAccess = expression.target as PropertyAccess;
+    expect(propertyAccess.propertyName.toSource(), 'baz');
+    var target = propertyAccess.target as PostfixExpression;
+    expect(target.operand.toSource(), 'foo.bar');
+    expect(target.operator.lexeme, '!');
+  }
+
   void test_nullCheckBeforeMethodCall() {
     parseCompilationUnit('f() { var x = g!.m() + 7; }');
   }
@@ -3119,21 +3035,6 @@
     expect(target.operand.toSource(), "foo");
   }
 
-  void test_nullCheckBeforeIndex() {
-    // https://github.com/dart-lang/sdk/issues/37708
-    var unit = parseCompilationUnit('f() { foo.bar!.baz[arg]; }');
-    var funct = unit.declarations[0] as FunctionDeclaration;
-    var body = funct.functionExpression.body as BlockFunctionBody;
-    var statement = body.block.statements[0] as ExpressionStatement;
-    var expression = statement.expression as IndexExpression;
-    expect(expression.index.toSource(), 'arg');
-    var propertyAccess = expression.target as PropertyAccess;
-    expect(propertyAccess.propertyName.toSource(), 'baz');
-    var target = propertyAccess.target as PostfixExpression;
-    expect(target.operand.toSource(), 'foo.bar');
-    expect(target.operator.lexeme, '!');
-  }
-
   void test_nullCheckOnLiteral_disabled() {
     parseCompilationUnit('f() { var x = 0!; }',
         errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 15, 1)],
@@ -4356,3 +4257,130 @@
     expect(declarationList.variables, hasLength(1));
   }
 }
+
+@reflectiveTest
+class VarianceParserTest_Fasta extends FastaParserTestCase {
+  @override
+  CompilationUnit parseCompilationUnit(String content,
+      {List<ErrorCode> codes,
+      List<ExpectedError> errors,
+      FeatureSet featureSet}) {
+    return super.parseCompilationUnit(content,
+        codes: codes,
+        errors: errors,
+        featureSet: featureSet ??
+            FeatureSet.forTesting(
+              sdkVersion: '2.5.0',
+              additionalFeatures: [Feature.variance],
+            ));
+  }
+
+  void test_class_disabled_multiple() {
+    parseCompilationUnit('class A<in T, inout U, out V> { }',
+        errors: [
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 2),
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 14, 5),
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 23, 3)
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_class_disabled_single() {
+    parseCompilationUnit('class A<out T> { }',
+        errors: [
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 3),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_class_enabled_multipleVariances() {
+    var unit = parseCompilationUnit('class A<in out inout T> { }', errors: [
+      expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 11, 3),
+      expectedError(ParserErrorCode.MULTIPLE_VARIANCE_MODIFIERS, 15, 5)
+    ]);
+    expect(unit.declarations, hasLength(1));
+    var classDecl = unit.declarations[0] as ClassDeclaration;
+    expect(classDecl.name.name, 'A');
+    expect(classDecl.typeParameters.typeParameters, hasLength(1));
+    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
+  }
+
+  void test_class_enabled_single() {
+    var unit = parseCompilationUnit('class A<in T> { }');
+    expect(unit.declarations, hasLength(1));
+    var classDecl = unit.declarations[0] as ClassDeclaration;
+    expect(classDecl.name.name, 'A');
+    expect(classDecl.typeParameters.typeParameters, hasLength(1));
+    expect(classDecl.typeParameters.typeParameters[0].name.name, 'T');
+  }
+
+  void test_function_disabled() {
+    parseCompilationUnit('void A(in int value) {}',
+        errors: [
+          expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
+          expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_function_enabled() {
+    parseCompilationUnit('void A(in int value) {}', errors: [
+      expectedError(ParserErrorCode.MISSING_IDENTIFIER, 7, 2),
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 10, 3),
+    ]);
+  }
+
+  void test_list_disabled() {
+    parseCompilationUnit('List<out String> stringList = [];',
+        errors: [
+          expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_list_enabled() {
+    parseCompilationUnit('List<out String> stringList = [];', errors: [
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 6),
+    ]);
+  }
+
+  void test_mixin_disabled_multiple() {
+    parseCompilationUnit('mixin A<inout T, out U> { }',
+        errors: [
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 17, 3),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_mixin_disabled_single() {
+    parseCompilationUnit('mixin A<inout T> { }',
+        errors: [
+          expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 8, 5),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_mixin_enabled_single() {
+    var unit = parseCompilationUnit('mixin A<inout T> { }');
+    expect(unit.declarations, hasLength(1));
+    var mixinDecl = unit.declarations[0] as MixinDeclaration;
+    expect(mixinDecl.name.name, 'A');
+    expect(mixinDecl.typeParameters.typeParameters, hasLength(1));
+    expect(mixinDecl.typeParameters.typeParameters[0].name.name, 'T');
+  }
+
+  void test_typedef_disabled() {
+    parseCompilationUnit('typedef A<inout X> = X Function(X);',
+        errors: [
+          expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
+        ],
+        featureSet: FeatureSet.forTesting(sdkVersion: '2.5.0'));
+  }
+
+  void test_typedef_enabled() {
+    parseCompilationUnit('typedef A<inout X> = X Function(X);', errors: [
+      expectedError(ParserErrorCode.EXPECTED_TOKEN, 16, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 1ff1558..6b7c83e 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -222,7 +222,7 @@
     if (token == null) {
       return;
     }
-    Token previousToken = null;
+    Token previousToken;
     int previousEnd = -1;
     Token currentToken = token;
     while (currentToken != null && currentToken.type != TokenType.EOF) {
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index b1a5532..eb0cec2 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1212,8 +1212,8 @@
       _assertHasPrevious(clone);
     }
     Token stopOriginalToken = originalNode.endToken.next;
-    Token skipCloneComment = null;
-    Token skipOriginalComment = null;
+    Token skipCloneComment;
+    Token skipOriginalComment;
     while (original != stopOriginalToken) {
       expect(clone, isNotNull);
       _assertEqualToken(clone, original);
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 03fb7a6..cfe7454 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -65,7 +65,7 @@
    * The path to the default SDK, or `null` if the test has not explicitly
    * invoked [createDefaultSdk].
    */
-  String defaultSdkPath = null;
+  String defaultSdkPath;
 
   _MockLintRule _mockLintRule;
   _MockLintRule _mockLintRule2;
diff --git a/pkg/analyzer/test/src/dart/analysis/base.dart b/pkg/analyzer/test/src/dart/analysis/base.dart
index 46ac748..29aeeb5 100644
--- a/pkg/analyzer/test/src/dart/analysis/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/base.dart
@@ -26,7 +26,7 @@
  * Finds an [Element] with the given [name].
  */
 Element findChildElement(Element root, String name, [ElementKind kind]) {
-  Element result = null;
+  Element result;
   root.accept(new _ElementVisitorFunctionWrapper((Element element) {
     if (element.name != name) {
       return;
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
index 7c00d1f..1e9c3fb 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_method_test.dart
@@ -56,6 +56,7 @@
 }
 ''', [
       error(ParserErrorCode.EXPECTED_TOKEN, 10, 1),
+      error(CompileTimeErrorCode.UNDEFINED_CLASS, 12, 0),
       error(ParserErrorCode.EXPECTED_TYPE_NAME, 12, 1),
       error(ParserErrorCode.EXTENSION_DECLARES_CONSTRUCTOR, 16, 1),
     ]);
diff --git a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
index e76fb1b..e9b17ee 100644
--- a/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/extension_override_test.dart
@@ -6,6 +6,7 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:meta/meta.dart';
 import 'package:test/test.dart';
@@ -316,6 +317,23 @@
     validateBinaryExpression();
   }
 
+  test_operator_onTearoff() async {
+    // https://github.com/dart-lang/sdk/issues/38653
+    await assertErrorsInCode('''
+f(){
+  E(null).v++;
+}
+extension E on Object{
+  v() {}
+}
+''', [
+      error(CompileTimeErrorCode.UNDEFINED_EXTENSION_SETTER, 15, 1),
+    ]);
+    findDeclarationAndOverride(
+        declarationName: 'E ', overrideSearch: 'E(null)');
+    validateOverride();
+  }
+
   test_operator_prefix_noTypeArguments() async {
     newFile('/test/lib/lib.dart', content: '''
 class A {}
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index c2520f8..c617a00 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -103,6 +103,7 @@
     expect(value.getField('a').getField('f').toIntValue(), 42);
   }
 
+  @FailingTest(reason: 'Reverted because of dartbug.com/38565')
   test_sameLibrary_genericClass_constructor_unnamed() async {
     await assertNoErrorsInCode(r'''
 class A<T> {
diff --git a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
index 9d2253f..97b6c70 100644
--- a/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/argument_type_not_assignable_test.dart
@@ -36,7 +36,7 @@
     // mismatch. Furthermore, the error message should mention both _A and the
     // filenames so the user can figure out what's going on.
     String message = result.errors[0].message;
-    expect(message.indexOf("_A") >= 0, isTrue);
+    expect(message.contains("_A"), isTrue);
   }
 
   test_annotation_namedConstructor() async {
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index 6831be1..4418dfc 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -69,15 +69,17 @@
   bool annotateNullability: false,
 }) {
   var writer = new _ElementWriter(
-      withCodeRanges: withCodeRanges,
-      withConstElements: withConstElements,
-      withExportScope: withExportScope,
-      withFullyResolvedAst: withFullyResolvedAst,
-      withOffsets: withOffsets,
-      withSyntheticAccessors: withSyntheticAccessors,
-      withSyntheticFields: withSyntheticFields,
-      withTypes: withTypes,
-      annotateNullability: annotateNullability);
+    selfUriStr: '${library.source.uri}',
+    withCodeRanges: withCodeRanges,
+    withConstElements: withConstElements,
+    withExportScope: withExportScope,
+    withFullyResolvedAst: withFullyResolvedAst,
+    withOffsets: withOffsets,
+    withSyntheticAccessors: withSyntheticAccessors,
+    withSyntheticFields: withSyntheticFields,
+    withTypes: withTypes,
+    annotateNullability: annotateNullability,
+  );
   writer.writeLibraryElement(library);
 
   String actualText = writer.buffer.toString();
@@ -138,6 +140,7 @@
  * Writes the canonical text presentation of elements.
  */
 class _ElementWriter {
+  final String selfUriStr;
   final bool withCodeRanges;
   final bool withExportScope;
   final bool withFullyResolvedAst;
@@ -149,16 +152,20 @@
   final bool annotateNullability;
   final StringBuffer buffer = new StringBuffer();
 
-  _ElementWriter(
-      {this.withCodeRanges,
-      this.withConstElements: true,
-      this.withExportScope: false,
-      this.withFullyResolvedAst: false,
-      this.withOffsets: false,
-      this.withSyntheticAccessors: false,
-      this.withSyntheticFields: false,
-      this.withTypes: false,
-      this.annotateNullability: false});
+  String indent = '';
+
+  _ElementWriter({
+    this.selfUriStr,
+    this.withCodeRanges,
+    this.withConstElements: true,
+    this.withExportScope: false,
+    this.withFullyResolvedAst: false,
+    this.withOffsets: false,
+    this.withSyntheticAccessors: false,
+    this.withSyntheticFields: false,
+    this.withTypes: false,
+    this.annotateNullability: false,
+  });
 
   bool isDynamicType(DartType type) => type is DynamicTypeImpl;
 
@@ -226,25 +233,35 @@
 
     buffer.writeln(' {');
 
-    e.fields.forEach(writePropertyInducingElement);
-    e.accessors.forEach(writePropertyAccessorElement);
+    _withIndent(() {
+      e.fields.forEach(writePropertyInducingElement);
+      e.accessors.forEach(writePropertyAccessorElement);
 
-    if (e.isEnum) {
-      expect(e.constructors, isEmpty);
-    } else {
-      expect(e.constructors, isNotEmpty);
-    }
+      if (e.isEnum) {
+        expect(e.constructors, isEmpty);
+      } else {
+        expect(e.constructors, isNotEmpty);
+      }
 
-    if (e.constructors.length == 1 &&
-        e.constructors[0].isSynthetic &&
-        e.mixins.isEmpty) {
-      expect(e.constructors[0].parameters, isEmpty);
-    } else {
-      e.constructors.forEach(writeConstructorElement);
-    }
+      if (e.constructors.length == 1 &&
+          e.constructors[0].isSynthetic &&
+          e.mixins.isEmpty) {
+        expect(e.constructors[0].parameters, isEmpty);
+      } else {
+        e.constructors.forEach(writeConstructorElement);
+      }
 
-    e.methods.forEach(writeMethodElement);
+      e.methods.forEach(writeMethodElement);
+    });
+
     buffer.writeln('}');
+
+    if (withFullyResolvedAst) {
+      _withIndent(() {
+        _writeResolvedMetadata(e.metadata);
+        _writeResolvedTypeParameters(e.typeParameters);
+      });
+    }
   }
 
   void writeCodeRange(Element e) {
@@ -292,16 +309,28 @@
       }
     }
 
-    if (e is ConstructorElementImpl) {
-      if (e.constantInitializers != null) {
-        writeList(' : ', '', e.constantInitializers, ', ', writeNode);
+    var initializers = (e as ConstructorElementImpl).constantInitializers;
+    if (withFullyResolvedAst) {
+      buffer.writeln(';');
+      if (initializers != null && initializers.isNotEmpty) {
+        _withIndent(() {
+          _writelnWithIndent('constantInitializers');
+          _withIndent(() {
+            for (var initializer in initializers) {
+              _writeResolvedNode(initializer);
+            }
+          });
+        });
       }
+    } else {
+      if (initializers != null) {
+        writeList(' : ', '', initializers, ', ', writeNode);
+      }
+      buffer.writeln(';');
     }
 
     expect(e.isAsynchronous, isFalse);
     expect(e.isGenerator, isFalse);
-
-    buffer.writeln(';');
   }
 
   void writeDocumentation(Element e, [String prefix = '']) {
@@ -355,10 +384,21 @@
     }
 
     buffer.writeln(' {');
-    e.fields.forEach(writePropertyInducingElement);
-    e.accessors.forEach(writePropertyAccessorElement);
-    e.methods.forEach(writeMethodElement);
+
+    _withIndent(() {
+      e.fields.forEach(writePropertyInducingElement);
+      e.accessors.forEach(writePropertyAccessorElement);
+      e.methods.forEach(writeMethodElement);
+    });
+
     buffer.writeln('}');
+
+    if (withFullyResolvedAst) {
+      _withIndent(() {
+        _writeResolvedMetadata(e.metadata);
+        _writeResolvedTypeParameters(e.typeParameters);
+      });
+    }
   }
 
   void writeFunctionElement(FunctionElement e) {
@@ -488,6 +528,10 @@
   }
 
   void writeMetadata(Element e, String prefix, String separator) {
+    if (withFullyResolvedAst) {
+      return;
+    }
+
     if (e.metadata.isNotEmpty) {
       writeList(prefix, '', e.metadata, '$separator$prefix', (a) {
         writeNode((a as ElementAnnotationImpl).annotationAst);
@@ -520,6 +564,13 @@
     } else {
       buffer.writeln(' {}');
     }
+
+    if (withFullyResolvedAst) {
+      _withIndent(() {
+        _writeResolvedTypeParameters(e.typeParameters);
+        _writeResolvedMetadata(e.metadata);
+      });
+    }
   }
 
   void writeName(Element e) {
@@ -540,14 +591,7 @@
     }
   }
 
-  void writeNode(AstNode e, {String indent: '', Expression enclosing}) {
-    if (withFullyResolvedAst) {
-      buffer.writeln();
-      var printer = ResolvedAstPrinter(buffer, indent);
-      e.accept(printer);
-      return;
-    }
-
+  void writeNode(AstNode e, {Expression enclosing}) {
     bool needsParenthesis = e is Expression &&
         enclosing != null &&
         e.precedence < enclosing.precedence;
@@ -961,25 +1005,35 @@
 
     writeVariableTypeInferenceError(e);
 
-    if (e is ConstVariableElement) {
-      Expression initializer = (e as ConstVariableElement).constantInitializer;
-      if (initializer != null) {
-        buffer.write(' = ');
-        writeNode(
-          initializer,
-          indent: ' ' * (e is FieldElement ? 4 : 2),
-        );
-        if (withFullyResolvedAst) {
-          return;
+    if (withFullyResolvedAst) {
+      buffer.writeln(';');
+      _withIndent(() {
+        _writeResolvedMetadata(e.metadata);
+        if (e is ConstVariableElement) {
+          var initializer = (e as ConstVariableElement).constantInitializer;
+          if (initializer != null) {
+            _writelnWithIndent('constantInitializer');
+            _withIndent(() {
+              _writeResolvedNode(initializer);
+            });
+          }
+        }
+      });
+    } else {
+      if (e is ConstVariableElement) {
+        Expression initializer =
+            (e as ConstVariableElement).constantInitializer;
+        if (initializer != null) {
+          buffer.write(' = ');
+          writeNode(initializer);
         }
       }
+      buffer.writeln(';');
     }
 
     // TODO(scheglov) Paul: One of the things that was hardest to get right
     // when resynthesizing the element model was the synthetic function for the
     // initializer.  Can we write that out (along with its return type)?
-
-    buffer.writeln(';');
   }
 
   void writeType(DartType type) {
@@ -1047,7 +1101,9 @@
   }
 
   void writeTypeParameterElements(List<TypeParameterElement> elements) {
-    writeList('<', '>', elements, ', ', writeTypeParameterElement);
+    if (!withFullyResolvedAst) {
+      writeList('<', '>', elements, ', ', writeTypeParameterElement);
+    }
   }
 
   void writeUnitElement(CompilationUnitElement e) {
@@ -1135,6 +1191,18 @@
     return components.join(';');
   }
 
+  void _withIndent(void Function() f) {
+    var indent = this.indent;
+    this.indent = '$indent  ';
+    f();
+    this.indent = indent;
+  }
+
+  void _writelnWithIndent(String line) {
+    buffer.write(indent);
+    buffer.writeln(line);
+  }
+
   bool _writeParameters(Iterable<ParameterElement> parameters, bool commaNeeded,
       String prefix, String suffix) {
     if (parameters.isEmpty) return commaNeeded;
@@ -1160,6 +1228,44 @@
     buffer.write(suffix);
     return commaNeeded;
   }
+
+  void _writeResolvedMetadata(List<ElementAnnotation> metadata) {
+    if (metadata.isNotEmpty) {
+      _writelnWithIndent('metadata');
+      _withIndent(() {
+        for (ElementAnnotationImpl annotation in metadata) {
+          _writeResolvedNode(annotation.annotationAst);
+        }
+      });
+    }
+  }
+
+  void _writeResolvedNode(AstNode node) {
+    buffer.write(indent);
+    node.accept(
+      ResolvedAstPrinter(
+        selfUriStr: selfUriStr,
+        sink: buffer,
+        indent: indent,
+      ),
+    );
+  }
+
+  void _writeResolvedTypeParameters(List<TypeParameterElement> elements) {
+    if (elements.isNotEmpty) {
+      _writelnWithIndent('typeParameters');
+      _withIndent(() {
+        for (TypeParameterElementImpl e in elements) {
+          _writelnWithIndent(e.name);
+          _withIndent(() {
+            _writelnWithIndent('bound: ${e.bound}');
+            _writelnWithIndent('defaultType: ${e.defaultType}');
+            _writeResolvedMetadata(e.metadata);
+          });
+        }
+      });
+    }
+  }
 }
 
 class _Replacement {
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 551cad1..93a5e30 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -4,26 +4,77 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+import 'package:meta/meta.dart';
 
 /// Prints AST as a tree, with properties and children.
 class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
-  StringSink _sink;
+  final String _selfUriStr;
+  final StringSink _sink;
   String _indent = '';
 
-  ResolvedAstPrinter(StringSink sink, String indent)
-      : _sink = sink,
+  ResolvedAstPrinter({
+    @required String selfUriStr,
+    @required StringSink sink,
+    @required String indent,
+  })  : _selfUriStr = selfUriStr,
+        _sink = sink,
         _indent = indent;
 
   @override
+  void visitAnnotation(Annotation node) {
+    _writeln('Annotation');
+    _withIndent(() {
+      _writeNode('arguments', node.arguments);
+      _writeNode('constructorName', node.constructorName);
+      _writeElement('element', node.element);
+      _writeNode('name', node.name);
+    });
+  }
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    _writeln('ArgumentList');
+    _withIndent(() {
+      _writeNodeList('arguments', node.arguments);
+    });
+  }
+
+  @override
   void visitCompilationUnit(CompilationUnit node) {
     super.visitCompilationUnit(node);
   }
 
   @override
-  void visitIntegerLiteral(IntegerLiteral node) {
-    _writeln('IntegerLiteral(${node.literal.lexeme})');
+  void visitConstructorName(ConstructorName node) {
+    _writeln('ConstructorName');
     _withIndent(() {
-      _writeln2('staticType: ', node.staticType);
+      _writeNode('name', node.name);
+      _writeNode('type', node.type);
+    });
+  }
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression node) {
+    _writeln('InstanceCreationExpression');
+    _withIndent(() {
+      _writeNode('argumentList', node.argumentList);
+      _writeNode('constructorName', node.constructorName);
+      _writeElement('staticElement', node.staticElement);
+      _writeType('staticType', node.staticType);
+    });
+  }
+
+  @override
+  void visitIntegerLiteral(IntegerLiteral node) {
+    _writeln('IntegerLiteral');
+    _withIndent(() {
+      _writelnWithIndent('literal: ${node.literal}');
+      _writeType('staticType', node.staticType);
     });
   }
 
@@ -31,13 +82,74 @@
   void visitListLiteral(ListLiteral node) {
     _writeln('ListLiteral');
     _withIndent(() {
-      _writeln2('isConst: ', node.isConst);
-      _writeln2('staticType: ', node.staticType);
-      _writeTypeArgumentList('typeArguments', node.typeArguments);
       _writeNodeList('elements', node.elements);
+      _writeType('staticType', node.staticType);
+      _writeNode('typeArguments', node.typeArguments);
     });
   }
 
+  @override
+  void visitRedirectingConstructorInvocation(
+    RedirectingConstructorInvocation node,
+  ) {
+    _writeln('RedirectingConstructorInvocation');
+    _withIndent(() {
+      _writeNode('argumentList', node.argumentList);
+      _writeNode('constructorName', node.constructorName);
+      _writeElement('staticElement', node.staticElement);
+    });
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    _writeln('SimpleIdentifier');
+    _withIndent(() {
+      _writeAuxiliaryElements('auxiliaryElements', node.auxiliaryElements);
+      _writeElement('staticElement', node.staticElement);
+      _writeType('staticType', node.staticType);
+      _writelnWithIndent('token: ${node.token}');
+    });
+  }
+
+  @override
+  void visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    _writeln('SuperConstructorInvocation');
+    _withIndent(() {
+      _writeNode('argumentList', node.argumentList);
+      _writeNode('constructorName', node.constructorName);
+      _writeElement('staticElement', node.staticElement);
+    });
+  }
+
+  @override
+  void visitTypeName(TypeName node) {
+    _writeln('TypeName');
+    _withIndent(() {
+      _writeNode('name', node.name);
+      _writeType('type', node.type);
+      _writeNode('typeArguments', node.typeArguments);
+    });
+  }
+
+  String _referenceToString(Reference reference) {
+    if (reference.parent.name == '@unit') {
+      var libraryUriStr = reference.parent.parent.name;
+      if (libraryUriStr == _selfUriStr) {
+        return 'self';
+      }
+      return libraryUriStr;
+    }
+
+    var name = reference.name;
+    if (name.startsWith('@')) {
+      return _referenceToString(reference.parent);
+    }
+    if (name.isEmpty) {
+      name = '•';
+    }
+    return _referenceToString(reference.parent) + '::$name';
+  }
+
   void _withIndent(void Function() f) {
     var indent = _indent;
     _indent = '$_indent  ';
@@ -45,32 +157,64 @@
     _indent = indent;
   }
 
+  void _writeAuxiliaryElements(String name, AuxiliaryElements elements) {
+    if (elements != null) {
+      throw UnimplementedError();
+    }
+  }
+
+  void _writeElement(String name, Element element) {
+    _sink.write(_indent);
+    _sink.write('$name: ');
+    if (element == null) {
+      _sink.writeln('<null>');
+    } else if (element is Member) {
+      _sink.writeln(_nameOfMemberClass(element));
+      _withIndent(() {
+        _writeElement('base', element.baseElement);
+        _writelnWithIndent('substitution: ${element.substitution.map}');
+      });
+    } else {
+      var reference = (element as ElementImpl).reference;
+      var referenceStr = _referenceToString(reference);
+      _sink.writeln(referenceStr);
+    }
+  }
+
   void _writeln(String line) {
-    _sink.write('$_indent');
     _sink.writeln(line);
   }
 
-  void _writeln2(String prefix, Object o) {
-    _sink.write('$_indent');
-    _sink.write(prefix);
-    _sink.writeln(o);
+  void _writelnWithIndent(String line) {
+    _sink.write(_indent);
+    _sink.writeln(line);
+  }
+
+  void _writeNode(String name, AstNode node) {
+    if (node != null) {
+      _sink.write(_indent);
+      _sink.write('$name: ');
+      node.accept(this);
+    }
   }
 
   void _writeNodeList(String name, NodeList nodeList) {
     if (nodeList.isNotEmpty) {
-      _writeln(name);
+      _writelnWithIndent(name);
       _withIndent(() {
-        nodeList.accept(this);
+        for (var node in nodeList) {
+          _sink.write(_indent);
+          node.accept(this);
+        }
       });
     }
   }
 
-  void _writeTypeArgumentList(String name, TypeArgumentList node) {
-    if (node != null) {
-      _writeln(name);
-      _withIndent(() {
-        node.arguments?.accept(this);
-      });
-    }
+  void _writeType(String name, DartType type) {
+    _writelnWithIndent('$name: $type');
+  }
+
+  static String _nameOfMemberClass(Member member) {
+    return '${member.runtimeType}';
   }
 }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 6785245..618e653 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -33,9 +33,6 @@
   /// The shared SDK bundle, computed once and shared among test invocations.
   static LinkedNodeBundle _sdkBundle;
 
-  @override
-  bool get isAstBasedSummary => true;
-
   LinkedNodeBundle get sdkBundle {
     if (_sdkBundle != null) return _sdkBundle;
 
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 86a1ada..54294ea 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1256,21 +1256,12 @@
 class C<T extends D> {}
 class D<T extends C> {}
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 notSimplyBounded class C<T extends D<dynamic>> {
 }
 notSimplyBounded class D<T extends C<dynamic>> {
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-notSimplyBounded class C<T extends D<dynamic>> {
-}
-notSimplyBounded class D<T extends C<D<dynamic>>> {
-}
-''');
-    }
   }
 
   test_class_notSimplyBounded_complex_by_reference_to_cycle() async {
@@ -1353,21 +1344,12 @@
 typedef F(G value);
 typedef G(F value);
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 notSimplyBounded typedef F = dynamic Function(dynamic Function(dynamic Function(dynamic)) value);
 notSimplyBounded typedef G = dynamic Function(dynamic Function(dynamic) value);
 notSimplyBounded class C<T extends dynamic Function(dynamic Function(dynamic Function(dynamic)))> {
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-notSimplyBounded typedef F = dynamic Function(dynamic Function(dynamic Function(...)) value);
-notSimplyBounded typedef G = dynamic Function(dynamic Function(dynamic Function(...)) value);
-notSimplyBounded class C<T extends dynamic Function(dynamic Function(...))> {
-}
-''');
-    }
   }
 
   test_class_notSimplyBounded_self() async {
@@ -2574,10 +2556,9 @@
   P2<int>(),
 ];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 class P<T> {
   const P();
 }
@@ -2592,27 +2573,7 @@
         P2/*location: test.dart;P2*/<
         int/*location: dart:core;int*/>()];
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(
-          library,
-          '''
-class P<T> {
-  const P();
-}
-class P1<T> extends P<T> {
-  const P1();
-}
-class P2<T> extends P<T> {
-  const P2();
-}
-const List<P<dynamic>> values = const /*typeArgs=dynamic*/[const /*typeArgs=dynamic*/
-        P1/*location: test.dart;P1*/(), const
-        P2/*location: test.dart;P2*/<
-        int/*location: dart:core;int*/>()];
-''',
-          withTypes: true);
-    }
+        withTypes: true);
   }
 
   test_const_invalid_field_const() async {
@@ -2728,8 +2689,7 @@
 import 'a.dart' as p;
 const V = const p.C<int, String>.named(1, '222');
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const C<int, String> V = const
         p/*location: test.dart;p*/.
@@ -2738,16 +2698,6 @@
         String/*location: dart:core;String*/>.
         named/*location: a.dart;C;named*/(1, '222');
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C<int, String> V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>.
-        named/*location: a.dart;C;named*/(1, '222');
-''');
-    }
   }
 
   test_const_invokeConstructor_generic_noTypeArguments() async {
@@ -2813,8 +2763,7 @@
 import 'a.dart' as p;
 const V = const p.C<int, String>();
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const C<int, String> V = const
         p/*location: test.dart;p*/.
@@ -2822,15 +2771,6 @@
         int/*location: dart:core;int*/,
         String/*location: dart:core;String*/>();
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C<int, String> V = const
-        C/*location: a.dart;C*/<
-        int/*location: dart:core;int*/,
-        String/*location: dart:core;String*/>();
-''');
-    }
   }
 
   test_const_invokeConstructor_named() async {
@@ -2840,8 +2780,7 @@
 }
 const V = const C.named(true, 1, 2, d: 'ccc', e: 3.4);
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   const C.named(bool a, int b, int c, {String d}, {double e});
 }
@@ -2851,18 +2790,6 @@
         d/*location: test.dart;C;named;d*/: 'ccc',
         e/*location: test.dart;C;named;e*/: 3.4);
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  const C.named(bool a, int b, int c, {String d}, {double e});
-}
-const C V = const
-        C/*location: test.dart;C*/.
-        named/*location: test.dart;C;named*/(true, 1, 2,
-        d/*location: null*/: 'ccc',
-        e/*location: null*/: 3.4);
-''');
-    }
   }
 
   test_const_invokeConstructor_named_imported() async {
@@ -2893,22 +2820,13 @@
 import 'a.dart' as p;
 const V = const p.C.named();
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const C V = const
         p/*location: test.dart;p*/.
         C/*location: a.dart;C*/.
         named/*location: a.dart;C;named*/();
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C V = const
-        C/*location: a.dart;C*/.
-        named/*location: a.dart;C;named*/();
-''');
-    }
   }
 
   test_const_invokeConstructor_named_unresolved() async {
@@ -2916,23 +2834,13 @@
 class C {}
 const V = const C.named();
 ''', allowErrors: true);
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
 }
 const C V = const
         C/*location: test.dart;C*/.
         named/*location: null*/();
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-}
-const dynamic V = const
-        C/*location: test.dart;C*/.
-        named/*location: null*/();
-''');
-    }
   }
 
   test_const_invokeConstructor_named_unresolved2() async {
@@ -2955,23 +2863,13 @@
 import 'a.dart' as p;
 const V = const p.C.named();
 ''', allowErrors: true);
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const C V = const
         p/*location: test.dart;p*/.
         C/*location: a.dart;C*/.
         named/*location: null*/();
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = const
-        p/*location: test.dart;p*/.
-        C/*location: a.dart;C*/.
-        named/*location: null*/();
-''');
-    }
   }
 
   test_const_invokeConstructor_named_unresolved4() async {
@@ -3006,23 +2904,13 @@
 class C<T> {}
 const V = const C.named();
 ''', allowErrors: true);
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C<T> {
 }
 const C<dynamic> V = const
         C/*location: test.dart;C*/.
         named/*location: null*/();
 ''');
-    } else {
-      checkElementText(library, r'''
-class C<T> {
-}
-const dynamic V = const
-        C/*location: test.dart;C*/.
-        named/*location: null*/();
-''');
-    }
   }
 
   test_const_invokeConstructor_unnamed() async {
@@ -3068,20 +2956,12 @@
 import 'a.dart' as p;
 const V = const p.C();
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const C V = const
         p/*location: test.dart;p*/.
         C/*location: a.dart;C*/();
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C V = const
-        C/*location: a.dart;C*/();
-''');
-    }
   }
 
   test_const_invokeConstructor_unnamed_unresolved() async {
@@ -3282,63 +3162,40 @@
     var library = await checkLibrary('''
 const Object x = const [1];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const /*typeArgs=int*/[1];
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>[1];
-''');
-    }
+        withTypes: true);
   }
 
   test_const_list_spread() async {
     var library = await checkLibrary('''
 const Object x = const <int>[...<int>[1]];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/>[...<
         int/*location: dart:core;int*/>[1]];
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>[...const <
-        int/*location: dart:core;int*/>[1]];
-''');
-    }
+        withTypes: true);
   }
 
   test_const_list_spread_null_aware() async {
     var library = await checkLibrary('''
 const Object x = const <int>[...?<int>[1]];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/>[...?<
         int/*location: dart:core;int*/>[1]];
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>[...?const <
-        int/*location: dart:core;int*/>[1]];
-''');
-    }
+        withTypes: true);
   }
 
   test_const_map_if() async {
@@ -3376,72 +3233,44 @@
     var library = await checkLibrary('''
 const Object x = const {1: 1.0};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const /*typeArgs=int,double*/{1: 1.0}/*isMap*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/,
-        double/*location: dart:core;double*/>{1: 1.0}/*isMap*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_map_spread() async {
     var library = await checkLibrary('''
 const Object x = const <int, int>{...<int, int>{1: 2}};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/,
         int/*location: dart:core;int*/>{...<
         int/*location: dart:core;int*/,
         int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/,
-        int/*location: dart:core;int*/>{...const <
-        int/*location: dart:core;int*/,
-        int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_map_spread_null_aware() async {
     var library = await checkLibrary('''
 const Object x = const <int, int>{...?<int, int>{1: 2}};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/,
         int/*location: dart:core;int*/>{...?<
         int/*location: dart:core;int*/,
         int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/,
-        int/*location: dart:core;int*/>{...?const <
-        int/*location: dart:core;int*/,
-        int/*location: dart:core;int*/>{1: 2}/*isMap*/}/*isMap*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_parameterDefaultValue_initializingFormal_functionTyped() async {
@@ -3938,63 +3767,40 @@
     var library = await checkLibrary('''
 const Object x = const {1};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const /*typeArgs=int*/{1}/*isSet*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>{1}/*isSet*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_set_spread() async {
     var library = await checkLibrary('''
 const Object x = const <int>{...<int>{1}};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/>{...<
         int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>{...const <
-        int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_set_spread_null_aware() async {
     var library = await checkLibrary('''
 const Object x = const <int>{...?<int>{1}};
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          '''
+    checkElementText(
+        library,
+        '''
 const Object x = const <
         int/*location: dart:core;int*/>{...?<
         int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, '''
-const Object x = const <
-        int/*location: dart:core;int*/>{...?const <
-        int/*location: dart:core;int*/>{1}/*isSet*/}/*isSet*/;
-''');
-    }
+        withTypes: true);
   }
 
   test_const_topLevel_binary() async {
@@ -4044,30 +3850,18 @@
     var library = await checkLibrary(r'''
 const vConditional = (1 == 2) ? 11 : 22;
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 const int vConditional = (1 == 2) ? 11 : 22;
 ''');
-    } else {
-      checkElementText(library, r'''
-const int vConditional = 1 == 2 ? 11 : 22;
-''');
-    }
   }
 
   test_const_topLevel_identical() async {
     var library = await checkLibrary(r'''
 const vIdentical = (1 == 2) ? 11 : 22;
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 const int vIdentical = (1 == 2) ? 11 : 22;
 ''');
-    } else {
-      checkElementText(library, r'''
-const int vIdentical = 1 == 2 ? 11 : 22;
-''');
-    }
   }
 
   test_const_topLevel_ifNull() async {
@@ -4159,16 +3953,9 @@
     var library = await checkLibrary(r'''
 const c = throw 42;
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 const dynamic c = throw 42;
 ''');
-    } else {
-      // This is a bug.
-      checkElementText(library, r'''
-const dynamic c;
-''');
-    }
   }
 
   test_const_topLevel_typedList() async {
@@ -4219,20 +4006,12 @@
 import 'a.dart' as p;
 const v = const <p.C>[];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const List<C> v = const <
         p/*location: test.dart;p*/.
         C/*location: a.dart;C*/>[];
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const List<C> v = const <
-        C/*location: a.dart;C*/>[];
-''');
-    }
   }
 
   test_const_topLevel_typedList_typedefArgument() async {
@@ -4240,21 +4019,11 @@
 typedef int F(String id);
 const v = const <F>[];
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 typedef F = int Function(String id);
 const List<int Function(String)> v = const <
         F/*location: test.dart;F*/>[];
 ''');
-    } else {
-      // This is wrong.
-      // `F` must be the reference to `typedef F` element, not the type.
-      checkElementText(library, r'''
-typedef F = int Function(String id);
-const List<int Function(String)> v = const <
-        null/*location: test.dart;F;-*/>[];
-''');
-    }
   }
 
   test_const_topLevel_typedMap() async {
@@ -4370,24 +4139,13 @@
   static const b = null;
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   static const dynamic a =
         b/*location: test.dart;C;b?*/;
   static const dynamic b = null;
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static const dynamic a =
-        C/*location: test.dart;C*/.
-        b/*location: test.dart;C;b?*/;
-  static const dynamic b = null;
-}
-''');
-    }
   }
 
   test_constExpr_pushReference_staticMethod_simpleIdentifier() async {
@@ -4397,24 +4155,13 @@
   static m() {}
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   static const dynamic Function() a =
         m/*location: test.dart;C;m*/;
   static dynamic m() {}
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  static const dynamic Function() a =
-        C/*location: test.dart;C*/.
-        m/*location: test.dart;C;m*/;
-  static dynamic m() {}
-}
-''');
-    }
   }
 
   test_constructor_documented() async {
@@ -4527,8 +4274,7 @@
    : this(A<Function()>());
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class A<T> {
   const A();
 }
@@ -4538,7 +4284,35 @@
         A/*location: test.dart;A*/<Function()>());
 }
 ''');
-    }
+  }
+
+  test_constructor_initializers_superInvocation_argumentContextType() async {
+    var library = await checkLibrary('''
+class A {
+  const A(List<String> values);
+}
+class B extends A {
+  const B() : super(const []);
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A(List<String> values);
+}
+class B extends A {
+  const B();
+    constantInitializers
+      SuperConstructorInvocation
+        argumentList: ArgumentList
+          arguments
+            ListLiteral
+              staticType: List<String>
+        staticElement: self::A::•
+}
+''',
+        withFullyResolvedAst: true);
   }
 
   test_constructor_initializers_superInvocation_named() async {
@@ -4590,8 +4364,7 @@
   const C() : super.aaa(1, b: 2);
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class A {
   const A.aaa(dynamic a, {int b});
 }
@@ -4601,18 +4374,6 @@
         b/*location: test.dart;A;aaa;b*/: 2);
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class A {
-  const A.aaa(dynamic a, {int b});
-}
-class C extends A {
-  const C() : super.
-        aaa/*location: test.dart;A;aaa*/(1,
-        b/*location: null*/: 2);
-}
-''');
-    }
   }
 
   test_constructor_initializers_superInvocation_unnamed() async {
@@ -4634,6 +4395,31 @@
 ''');
   }
 
+  test_constructor_initializers_thisInvocation_argumentContextType() async {
+    var library = await checkLibrary('''
+class A {
+  const A(List<String> values);
+  const A.empty() : this(const []);
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A(List<String> values);
+  const A.empty() = A;
+    constantInitializers
+      RedirectingConstructorInvocation
+        argumentList: ArgumentList
+          arguments
+            ListLiteral
+              staticType: List<String>
+        staticElement: self::A::•
+}
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_constructor_initializers_thisInvocation_named() async {
     var library = await checkLibrary('''
 class C {
@@ -4657,8 +4443,7 @@
   const C.named(a, {int b});
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   const C() = C.named : this.
         named/*location: test.dart;C;named*/(1,
@@ -4666,16 +4451,6 @@
   const C.named(dynamic a, {int b});
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  const C() = C.named : this.
-        named/*location: test.dart;C;named*/(1,
-        b/*location: null*/: 2);
-  const C.named(dynamic a, {int b});
-}
-''');
-    }
   }
 
   test_constructor_initializers_thisInvocation_unnamed() async {
@@ -5042,21 +4817,12 @@
   C() : this.named();
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   C.named();
   C();
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  C.named();
-  C() = C.named;
-}
-''');
-    }
   }
 
   test_constructor_redirected_thisInvocation_unnamed() async {
@@ -5096,21 +4862,12 @@
   C.named() : this();
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   C();
   C.named();
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  C();
-  C.named() = C;
-}
-''');
-    }
   }
 
   test_constructor_withCycles_const() async {
@@ -5194,8 +4951,7 @@
   void foo({a: const A<Function()>()}) {}
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class A<T> {
   const A();
 }
@@ -5204,7 +4960,6 @@
         A/*location: test.dart;A*/<Function()>()}) {}
 }
 ''');
-    }
   }
 
   test_defaultValue_refersToExtension_method_inside() async {
@@ -5259,10 +5014,9 @@
   const C([B<T> b = const B()]);
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 class B<T> {
   const B();
 }
@@ -5271,18 +5025,7 @@
         B/*location: test.dart;B*/()]);
 }
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C<T> {
-  const C([B<T> b = const
-        B/*location: test.dart;B*/()]);
-}
-''');
-    }
+        withTypes: true);
   }
 
   test_defaultValue_refersToGenericClass_constructor2() async {
@@ -5295,10 +5038,9 @@
   const C([A<T> a = const B()]);
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 abstract class A<T> {
 }
 class B<T> implements A<T> {
@@ -5309,20 +5051,7 @@
         B/*location: test.dart;B*/()]);
 }
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-abstract class A<T> {
-}
-class B<T> implements A<T> {
-  const B();
-}
-class C<T> implements A<Iterable<T>> {
-  const C([A<T> a = const
-        B/*location: test.dart;B*/()]);
-}
-''');
-    }
+        withTypes: true);
   }
 
   test_defaultValue_refersToGenericClass_functionG() async {
@@ -5332,26 +5061,16 @@
 }
 void foo<T>([B<T> b = const B()]) {}
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 class B<T> {
   const B();
 }
 void foo<T>([B<T> b = const /*typeArgs=Null*/
         B/*location: test.dart;B*/()]) {}
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-void foo<T>([B<T> b = const
-        B/*location: test.dart;B*/()]) {}
-''');
-    }
+        withTypes: true);
   }
 
   test_defaultValue_refersToGenericClass_methodG() async {
@@ -5363,10 +5082,9 @@
   void foo<T>([B<T> b = const B()]) {}
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 class B<T> {
   const B();
 }
@@ -5375,18 +5093,7 @@
         B/*location: test.dart;B*/()]) {}
 }
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C {
-  void foo<T>([B<T> b = const
-        B/*location: test.dart;B*/()]) {}
-}
-''');
-    }
+        withTypes: true);
   }
 
   test_defaultValue_refersToGenericClass_methodG_classG() async {
@@ -5398,10 +5105,9 @@
   void foo<E2>([B<E1, E2> b = const B()]) {}
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 class B<T1, T2> {
   const B();
 }
@@ -5410,18 +5116,7 @@
         B/*location: test.dart;B*/()]) {}
 }
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-class B<T1, T2> {
-  const B();
-}
-class C<E1> {
-  void foo<E2>([B<E1, E2> b = const
-        B/*location: test.dart;B*/()]) {}
-}
-''');
-    }
+        withTypes: true);
   }
 
   test_defaultValue_refersToGenericClass_methodNG() async {
@@ -5433,10 +5128,9 @@
   void foo([B<T> b = const B()]) {}
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(
-          library,
-          r'''
+    checkElementText(
+        library,
+        r'''
 class B<T> {
   const B();
 }
@@ -5445,18 +5139,7 @@
         B/*location: test.dart;B*/()]) {}
 }
 ''',
-          withTypes: true);
-    } else {
-      checkElementText(library, r'''
-class B<T> {
-  const B();
-}
-class C<T> {
-  void foo([B<T> b = const
-        B/*location: test.dart;B*/()]) {}
-}
-''');
-    }
+        withTypes: true);
   }
 
   test_duplicateDeclaration_class() async {
@@ -6234,8 +5917,7 @@
   const B();
 }
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class A<T> {
   const A();
 }
@@ -6247,7 +5929,6 @@
   const B();
 }
 ''');
-    }
   }
 
   test_field_final_hasInitializer_noConstConstructor() async {
@@ -6431,10 +6112,10 @@
         library,
         r'''
 class C1 {
-  final List<int> f1 =
-    ListLiteral
-      isConst: true
-      staticType: List<int>
+  final List<int> f1;
+    constantInitializer
+      ListLiteral
+        staticType: List<int>
   const C1();
 }
 class C2 {
@@ -6832,15 +6513,9 @@
     var library = await checkLibrary('''
 typedef F<X extends F> = Function(F);
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 notSimplyBounded typedef F<X> = dynamic Function();
 ''');
-    } else {
-      checkElementText(library, r'''
-notSimplyBounded typedef F<X extends dynamic Function(...)> = dynamic Function(dynamic Function(...) );
-''');
-    }
   }
 
   test_getter_documented() async {
@@ -6894,8 +6569,7 @@
 }
 const x = C.named(42);
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
   final Object x;
   const C.named(Object this.x);
@@ -6904,17 +6578,6 @@
         C/*location: test.dart;C*/.
         named/*location: test.dart;C;named*/(42);
 ''');
-    } else {
-      checkElementText(library, r'''
-class C {
-  final Object x;
-  const C.named(Object this.x);
-}
-const C x = const
-        C/*location: test.dart;C*/.
-        named/*location: test.dart;C;named*/(42);
-''');
-    }
   }
 
   test_implicitTopLevelVariable_getterFirst() async {
@@ -8047,19 +7710,11 @@
 import 'c.dart';
 foo([p = V]) {}
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'c.dart';
 dynamic foo([dynamic p =
         V/*location: a.dart;V*/]) {}
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'c.dart';
-dynamic foo([dynamic p =
-        V/*location: null*/]) {}
-''');
-    }
   }
 
   test_invalid_nameConflict_local() async {
@@ -8068,21 +7723,12 @@
 V() {}
 var V;
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 dynamic V;
 dynamic foo([dynamic p =
         V/*location: test.dart;V?*/]) {}
 dynamic V() {}
 ''');
-    } else {
-      checkElementText(library, r'''
-dynamic V;
-dynamic foo([dynamic p =
-        V/*location: null*/]) {}
-dynamic V() {}
-''');
-    }
   }
 
   test_invalid_setterParameter_fieldFormalParameter() async {
@@ -8459,6 +8105,62 @@
 ''');
   }
 
+  test_metadata_class_scope() async {
+    var library = await checkLibrary(r'''
+const foo = 0;
+
+@foo
+class C<@foo T> {
+  static const foo = 1;
+  @foo
+  void bar() {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class C {
+  static const int foo;
+    constantInitializer
+      IntegerLiteral
+        literal: 1
+        staticType: int
+  void bar() {}
+    metadata
+      Annotation
+        element: self::C::foo
+        name: SimpleIdentifier
+          staticElement: self::C::foo
+          staticType: int
+          token: foo
+}
+  metadata
+    Annotation
+      element: self::foo
+      name: SimpleIdentifier
+        staticElement: self::foo
+        staticType: int
+        token: foo
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
+      metadata
+        Annotation
+          element: self::foo
+          name: SimpleIdentifier
+            staticElement: self::foo
+            staticType: int
+            token: foo
+const int foo;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_metadata_classDeclaration() async {
     var library = await checkLibrary(r'''
 const a = null;
@@ -8522,8 +8224,7 @@
 @foo.A.named()
 class C {}
 ''');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'foo.dart' as foo;
 @
         foo/*location: test.dart;foo*/.
@@ -8532,16 +8233,6 @@
 class C {
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
-        A/*location: foo.dart;A*/.
-        named/*location: foo.dart;A;named*/()
-class C {
-}
-''');
-    }
   }
 
   test_metadata_constructor_call_unnamed() async {
@@ -8561,8 +8252,7 @@
     addLibrarySource('/foo.dart', 'class A { const A(); }');
     var library =
         await checkLibrary('import "foo.dart" as foo; @foo.A() class C {}');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'foo.dart' as foo;
 @
         foo/*location: test.dart;foo*/.
@@ -8570,15 +8260,6 @@
 class C {
 }
 ''');
-    } else {
-      checkElementText(library, r'''
-import 'foo.dart' as foo;
-@
-        A/*location: foo.dart;A*/()
-class C {
-}
-''');
-    }
   }
 
   test_metadata_constructor_call_with_args() async {
@@ -8661,6 +8342,63 @@
 ''');
   }
 
+  test_metadata_extension_scope() async {
+    featureSet = enableExtensionMethods;
+    var library = await checkLibrary(r'''
+const foo = 0;
+
+@foo
+extension E<@foo T> on int {
+  static const foo = 1;
+  @foo
+  void bar() {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+extension E on int {
+  static const int foo;
+    constantInitializer
+      IntegerLiteral
+        literal: 1
+        staticType: int
+  void bar() {}
+    metadata
+      Annotation
+        element: self::E::foo
+        name: SimpleIdentifier
+          staticElement: self::E::foo
+          staticType: int
+          token: foo
+}
+  metadata
+    Annotation
+      element: self::foo
+      name: SimpleIdentifier
+        staticElement: self::foo
+        staticType: int
+        token: foo
+  typeParameters
+    T
+      bound: null
+      defaultType: null
+      metadata
+        Annotation
+          element: self::foo
+          name: SimpleIdentifier
+            staticElement: self::foo
+            staticType: int
+            token: foo
+const int foo;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_metadata_extensionDeclaration() async {
     featureSet = enableExtensionMethods;
     var library = await checkLibrary(r'''
@@ -8819,23 +8557,13 @@
 
   test_metadata_invalid_classDeclaration() async {
     var library = await checkLibrary('f(_) {} @f(42) class C {}');
-    if (isAstBasedSummary) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 @
         f/*location: test.dart;f*/(42)
 class C {
 }
 dynamic f(dynamic _) {}
 ''');
-    } else {
-      checkElementText(library, r'''
-@
-        __unresolved__/*location: null*/
-class C {
-}
-dynamic f(dynamic _) {}
-''');
-    }
   }
 
   test_metadata_libraryDirective() async {
@@ -8925,6 +8653,62 @@
 ''');
   }
 
+  test_metadata_mixin_scope() async {
+    var library = await checkLibrary(r'''
+const foo = 0;
+
+@foo
+mixin M<@foo T> {
+  static const foo = 1;
+  @foo
+  void bar() {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+mixin M on Object {
+  static const int foo;
+    constantInitializer
+      IntegerLiteral
+        literal: 1
+        staticType: int
+  void bar() {}
+    metadata
+      Annotation
+        element: self::M::foo
+        name: SimpleIdentifier
+          staticElement: self::M::foo
+          staticType: int
+          token: foo
+}
+  metadata
+    Annotation
+      element: self::foo
+      name: SimpleIdentifier
+        staticElement: self::foo
+        staticType: int
+        token: foo
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
+      metadata
+        Annotation
+          element: self::foo
+          name: SimpleIdentifier
+            staticElement: self::foo
+            staticType: int
+            token: foo
+const int foo;
+  constantInitializer
+    IntegerLiteral
+      literal: 0
+      staticType: int
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_metadata_mixinDeclaration() async {
     var library = await checkLibrary(r'''
 const a = null;
@@ -10107,25 +9891,15 @@
 var a = A(() => b);
 var b = A(() => a);
 ''');
-    if (isAstBasedSummary) {
-      // There is no cycle with `a` and `b`, because `A` is not generic,
-      // so the type of `new A(...)` does not depend on its arguments.
-      checkElementText(library, '''
+    // There is no cycle with `a` and `b`, because `A` is not generic,
+    // so the type of `new A(...)` does not depend on its arguments.
+    checkElementText(library, '''
 class A {
   A(dynamic _);
 }
 A a;
 A b;
 ''');
-    } else {
-      checkElementText(library, '''
-class A {
-  A(dynamic _);
-}
-dynamic a/*error: dependencyCycle*/;
-dynamic b/*error: dependencyCycle*/;
-''');
-    }
   }
 
   test_type_inference_multiplyDefinedElement() async {
@@ -11416,6 +11190,42 @@
 ''');
   }
 
+  test_variableInitializer_contextType_after_astRewrite() async {
+    var library = await checkLibrary(r'''
+class A<T> {
+  const A();
+}
+const A<int> a = A();
+''');
+    checkElementText(
+        library,
+        r'''
+class A {
+  const A();
+}
+  typeParameters
+    T
+      bound: null
+      defaultType: dynamic
+const A<int> a;
+  constantInitializer
+    InstanceCreationExpression
+      argumentList: ArgumentList
+      constructorName: ConstructorName
+        type: TypeName
+          name: SimpleIdentifier
+            staticElement: self::A
+            staticType: A<dynamic>
+            token: A
+          type: A<int>
+      staticElement: ConstructorMember
+        base: self::A::•
+        substitution: {T: int}
+      staticType: A<int>
+''',
+        withFullyResolvedAst: true);
+  }
+
   test_variables() async {
     var library = await checkLibrary('int i; int j;');
     checkElementText(library, r'''
diff --git a/pkg/analyzer/test/src/summary/test_strategies.dart b/pkg/analyzer/test/src/summary/test_strategies.dart
index 83e49ed..0fc7bdc 100644
--- a/pkg/analyzer/test/src/summary/test_strategies.dart
+++ b/pkg/analyzer/test/src/summary/test_strategies.dart
@@ -54,8 +54,6 @@
 
   set declaredVariables(DeclaredVariables declaredVariables);
 
-  bool get isAstBasedSummary => false;
-
   MemoryResourceProvider get resourceProvider;
 
   void set testFile(String value);
@@ -84,9 +82,6 @@
       <String, UnlinkedUnitBuilder>{};
 
   PackageBundleAssembler bundleAssembler = new PackageBundleAssembler();
-
-  @override
-  bool get isAstBasedSummary => false;
 }
 
 /// [SerializedMockSdk] is a singleton class representing the result of
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 2158740..36d5eb0 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -3394,9 +3394,7 @@
   }
 
   test_inferTypesOnGenericInstantiationsInLibraryCycle() async {
-    // Note: this is a regression test for a non-deterministic behavior we used to
-    // have with inference in library cycles. If you see this test flake out,
-    // change `test` to `skip_test` and reopen bug #48.
+    // Note: this is a regression test for bug #48.
     addFile('''
 import 'main.dart';
 abstract class I<E> {
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 0a8d7ee..fc52165 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -224,7 +224,7 @@
 class AbstractStrongTest with ResourceProviderMixin {
   bool _checkCalled = true;
 
-  AnalysisDriver _driver = null;
+  AnalysisDriver _driver;
 
   Map<String, List<Folder>> packageMap;
 
diff --git a/pkg/analyzer/test/verify_diagnostics_test.dart b/pkg/analyzer/test/verify_diagnostics_test.dart
index b881193..e829ba7 100644
--- a/pkg/analyzer/test/verify_diagnostics_test.dart
+++ b/pkg/analyzer/test/verify_diagnostics_test.dart
@@ -120,9 +120,6 @@
     } else if (snippet.indexOf(errorRangeStart, rangeEnd) > 0) {
       _reportProblem('More than one error range in example');
     }
-    if (snippet.indexOf('extension') >= 0) {
-      DateTime.now();
-    }
     return _SnippetData(
         snippet.substring(0, rangeStart) +
             snippet.substring(rangeStart + errorRangeStart.length, rangeEnd) +
diff --git a/pkg/analyzer/tool/diagnostics/generate.dart b/pkg/analyzer/tool/diagnostics/generate.dart
index 7f51a0d..c5f56bf 100644
--- a/pkg/analyzer/tool/diagnostics/generate.dart
+++ b/pkg/analyzer/tool/diagnostics/generate.dart
@@ -73,7 +73,7 @@
     List<CodePath> paths = [];
     for (int i = 0; i < documentationPaths.length; i++) {
       String docPath = pathContext.joinAll(documentationPaths[i]);
-      String declPath = null;
+      String declPath;
       if (declarationPaths[i] != null) {
         declPath = pathContext.joinAll(declarationPaths[i]);
       }
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 8e9c085..7e9a695 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -218,6 +218,8 @@
   /// Returns `true` if [element] is a superclass of `List`.
   bool isListSupertype(ClassEntity element);
 
+  InterfaceType getConstantListTypeFor(InterfaceType sourceType);
+
   InterfaceType getConstantMapTypeFor(InterfaceType sourceType,
       {bool hasProtoKey: false, bool onlyStringKeys: false});
 
@@ -1016,6 +1018,12 @@
   }
 
   @override
+  InterfaceType getConstantListTypeFor(InterfaceType sourceType) =>
+      sourceType.treatAsRaw
+          ? _env.getRawType(jsArrayClass)
+          : _env.createInterfaceType(jsArrayClass, sourceType.typeArguments);
+
+  @override
   InterfaceType getConstantMapTypeFor(InterfaceType sourceType,
       {bool hasProtoKey: false, bool onlyStringKeys: false}) {
     ClassEntity classElement = onlyStringKeys
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index 47aa5ed..566c2b9 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -87,8 +87,12 @@
     new StringConstantValue(string);
 BoolConstantValue createBool(bool value) => new BoolConstantValue(value);
 NullConstantValue createNull() => new NullConstantValue();
-ListConstantValue createList(InterfaceType type, List<ConstantValue> values) =>
-    new ListConstantValue(type, values);
+
+ListConstantValue createList(CommonElements commonElements,
+    InterfaceType sourceType, List<ConstantValue> values) {
+  InterfaceType type = commonElements.getConstantListTypeFor(sourceType);
+  return ListConstantValue(type, values);
+}
 
 ConstantValue createType(CommonElements commonElements, DartType type) {
   InterfaceType instanceType = commonElements.typeLiteralType;
@@ -174,7 +178,7 @@
   } else {
     keysType = commonElements.listType(sourceType.typeArguments.first);
   }
-  ListConstantValue keysList = new ListConstantValue(keysType, keys);
+  ListConstantValue keysList = createList(commonElements, keysType, keys);
   InterfaceType type = commonElements.getConstantMapTypeFor(sourceType,
       hasProtoKey: hasProtoKey, onlyStringKeys: onlyStringKeys);
   return new JavaScriptMapConstant(
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 61be000..095bec3 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -375,8 +375,8 @@
 
   @override
   ConstantValue evaluate(EvaluationEnvironment environment) {
-    return constant_system.createList(
-        type, values.map((v) => v.evaluate(environment)).toList());
+    return constant_system.createList(environment.commonElements, type,
+        values.map((v) => v.evaluate(environment)).toList());
   }
 
   @override
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index 6ff3566..3c39f11 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -353,7 +353,8 @@
 
   @override
   void handleAsExpression(ir.AsExpression node, ir.DartType operandType) {
-    if (typeEnvironment.isSubtypeOf(operandType, node.type)) {
+    if (typeEnvironment.isSubtypeOf(
+        operandType, node.type, ir.SubtypeCheckMode.ignoringNullabilities)) {
       // Skip unneeded casts.
       return;
     }
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 084ffd0..d686190 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -286,7 +286,8 @@
                 getTypeAsInstanceOf(receiverType, superclass));
         ir.DartType setterType =
             receiverSubstitution.substituteType(interfaceTarget.setterType);
-        if (!typeEnvironment.isSubtypeOf(valueType, setterType)) {
+        if (!typeEnvironment.isSubtypeOf(
+            valueType, setterType, ir.SubtypeCheckMode.ignoringNullabilities)) {
           // We need to insert an implicit cast to preserve the invariant that
           // a property set with a known interface target is also statically
           // checked.
@@ -484,7 +485,8 @@
     for (int i = 0; i < node.arguments.positional.length; i++) {
       ir.DartType argumentType = argumentTypes.positional[i];
       ir.DartType parameterType = parameterTypes.positionalParameters[i];
-      if (!typeEnvironment.isSubtypeOf(argumentType, parameterType)) {
+      if (!typeEnvironment.isSubtypeOf(argumentType, parameterType,
+          ir.SubtypeCheckMode.ignoringNullabilities)) {
         neededPositionalChecks[i] = parameterType;
       }
     }
@@ -497,7 +499,8 @@
       ir.DartType parameterType = parameterTypes.namedParameters
           .singleWhere((namedType) => namedType.name == namedArgument.name)
           .type;
-      if (!typeEnvironment.isSubtypeOf(argumentType, parameterType)) {
+      if (!typeEnvironment.isSubtypeOf(argumentType, parameterType,
+          ir.SubtypeCheckMode.ignoringNullabilities)) {
         neededNamedChecks[argumentIndex] = parameterType;
       }
     }
@@ -719,7 +722,8 @@
     assert(
         node.promotedType == null ||
             promotedType == typeEnvironment.nullType ||
-            typeEnvironment.isSubtypeOf(promotedType, node.promotedType),
+            typeEnvironment.isSubtypeOf(promotedType, node.promotedType,
+                ir.SubtypeCheckMode.ignoringNullabilities),
         "Unexpected promotion of ${node.variable} in ${node.parent}. "
         "Expected ${node.promotedType}, found $promotedType");
     _expressionTypeCache[node] = promotedType;
@@ -1474,7 +1478,8 @@
       // TODO(johnniwinther): Special-case the `== null` representation to
       // make it faster.
       for (ir.DartType type in falseTypes) {
-        if (typeEnvironment.isSubtypeOf(declaredType, type)) {
+        if (typeEnvironment.isSubtypeOf(
+            declaredType, type, ir.SubtypeCheckMode.ignoringNullabilities)) {
           return typeEnvironment.nullType;
         }
       }
@@ -1484,9 +1489,11 @@
         if (type == typeEnvironment.nullType) {
           return type;
         }
-        if (typeEnvironment.isSubtypeOf(type, candidate)) {
+        if (typeEnvironment.isSubtypeOf(
+            type, candidate, ir.SubtypeCheckMode.ignoringNullabilities)) {
           candidate = type;
-        } else if (!typeEnvironment.isSubtypeOf(candidate, type)) {
+        } else if (!typeEnvironment.isSubtypeOf(
+            candidate, type, ir.SubtypeCheckMode.ignoringNullabilities)) {
           // We cannot promote. No single type is most specific.
           // TODO(johnniwinther): Compute implied types? For instance when the
           // declared type is `Iterable<String>` and tested type is
@@ -1745,9 +1752,11 @@
           // Keep the current candidate.
         } else if (candidate == typeEnvironment.nullType) {
           candidate = type;
-        } else if (typeEnvironment.isSubtypeOf(candidate, type)) {
+        } else if (typeEnvironment.isSubtypeOf(
+            candidate, type, ir.SubtypeCheckMode.ignoringNullabilities)) {
           candidate = type;
-        } else if (!typeEnvironment.isSubtypeOf(type, candidate)) {
+        } else if (!typeEnvironment.isSubtypeOf(
+            type, candidate, ir.SubtypeCheckMode.ignoringNullabilities)) {
           // We cannot promote. No promoted type of one path is a supertype of
           // the promoted type from all other paths.
           // TODO(johnniwinther): Compute a greatest lower bound, instead?
@@ -1872,7 +1881,8 @@
         changed = true;
         Set<ir.DartType> newTypesOfInterest = new Set<ir.DartType>();
         for (ir.DartType typeOfInterest in info.typesOfInterest) {
-          if (typeEnvironment.isSubtypeOf(type, typeOfInterest)) {
+          if (typeEnvironment.isSubtypeOf(type, typeOfInterest,
+              ir.SubtypeCheckMode.ignoringNullabilities)) {
             newTypesOfInterest.add(typeOfInterest);
           }
         }
diff --git a/pkg/compiler/lib/src/ir/visitors.dart b/pkg/compiler/lib/src/ir/visitors.dart
index 6c08757..b41805a 100644
--- a/pkg/compiler/lib/src/ir/visitors.dart
+++ b/pkg/compiler/lib/src/ir/visitors.dart
@@ -728,7 +728,8 @@
     }
     DartType type = elementMap.commonElements
         .listType(elementMap.getDartType(node.typeArgument));
-    return constant_system.createList(type, elements);
+    return constant_system.createList(
+        elementMap.commonElements, type, elements);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index b9a78c9..b7dfa1a 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -473,10 +473,7 @@
 
   jsAst.Expression maybeAddListTypeArgumentsNewRti(
       ConstantValue constant, InterfaceType type, jsAst.Expression value) {
-    // List<T> --> JSArray<T>
-    if (type.element != _commonElements.jsArrayClass) {
-      type = InterfaceType(_commonElements.jsArrayClass, type.typeArguments);
-    }
+    assert(type.element == _commonElements.jsArrayClass);
     if (_rtiNeed.classNeedsTypeArguments(type.element)) {
       return new jsAst.Call(
           getHelperProperty(_commonElements.setRuntimeTypeInfo),
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index b6f90d4..13fbaf9 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -35,57 +35,6 @@
 
   InterceptorData get _interceptorData => _closedWorld.interceptorData;
 
-  jsAst.Expression generateClassConstructor(
-      ClassEntity classElement, List<jsAst.Name> fields, bool hasRtiField) {
-    // TODO(sra): Implement placeholders in VariableDeclaration position:
-    //
-    //     String constructorName = namer.getNameOfClass(classElement);
-    //     return js.statement('function #(#) { #; }',
-    //        [ constructorName, fields,
-    //            fields.map(
-    //                (name) => js('this.# = #', [name, name]))]));
-    dynamic typeParameters = const <jsAst.Parameter>[];
-    dynamic typeInits = const <jsAst.Expression>[];
-    if (hasRtiField) {
-      dynamic rtiName = _namer.rtiFieldJsName;
-      typeParameters = rtiName;
-      typeInits = js('this.# = #', [rtiName, rtiName]);
-    }
-    List<jsAst.Parameter> parameters = new List<jsAst.Parameter>.generate(
-        fields.length, (i) => new jsAst.Parameter('t$i'));
-    List<jsAst.Expression> fieldInitializers =
-        new List<jsAst.Expression>.generate(fields.length, (i) {
-      return js('this.# = #', [fields[i], parameters[i]]);
-    });
-    return js('function(#, #) { #; #; this.#();}', [
-      parameters,
-      typeParameters,
-      fieldInitializers,
-      typeInits,
-      _namer.fixedNames.deferredAction
-    ]);
-  }
-
-  jsAst.Expression generateGetter(MemberEntity member, jsAst.Name fieldName) {
-    ClassEntity cls = member.enclosingClass;
-    String receiver =
-        _interceptorData.isInterceptedClass(cls) ? 'receiver' : 'this';
-    List<String> args =
-        _interceptorData.isInterceptedMethod(member) ? ['receiver'] : [];
-    return js('function(#) { return #.# }', [args, receiver, fieldName]);
-  }
-
-  jsAst.Expression generateSetter(MemberEntity member, jsAst.Name fieldName) {
-    ClassEntity cls = member.enclosingClass;
-    String receiver =
-        _interceptorData.isInterceptedClass(cls) ? 'receiver' : 'this';
-    List<String> args =
-        _interceptorData.isInterceptedMethod(member) ? ['receiver'] : [];
-    // TODO(floitsch): remove 'return'?
-    return js(
-        'function(#, v) { return #.# = v; }', [args, receiver, fieldName]);
-  }
-
   /// Documentation wanted -- johnniwinther
   ///
   /// Invariant: [member] must be a declaration element.
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index 78da253..4e4571e 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -847,7 +847,8 @@
         if (member.isAbstract) {
           cls = elementMap.elementEnvironment.getSuperClass(cls);
         } else {
-          return member.enclosingClass != commonElements.objectClass;
+          return member.enclosingClass != commonElements.objectClass &&
+              member.enclosingClass != commonElements.jsInterceptorClass;
         }
       }
       return false;
diff --git a/pkg/dart2native/bin/dart2native.dart b/pkg/dart2native/bin/dart2native.dart
index f15d5d2..475c993 100644
--- a/pkg/dart2native/bin/dart2native.dart
+++ b/pkg/dart2native/bin/dart2native.dart
@@ -140,12 +140,13 @@
   }[parsedArgs['output-kind']];
 
   final sourcePath = path.canonicalize(path.normalize(parsedArgs.rest[0]));
+  final sourceWithoutDart = sourcePath.replaceFirst(new RegExp(r'\.dart$'), '');
   final outputPath =
       path.canonicalize(path.normalize(parsedArgs['output'] != null
           ? parsedArgs['output']
           : {
-              Kind.aot: '${sourcePath}.aot',
-              Kind.exe: '${sourcePath}.exe',
+              Kind.aot: '${sourceWithoutDart}.aot',
+              Kind.exe: '${sourceWithoutDart}.exe',
             }[kind]));
 
   if (!FileSystemEntity.isFileSync(sourcePath)) {
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 645dd90..4a2f6e6 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -446,10 +446,14 @@
   /// Returns the canonical name to refer to the Dart library.
   @protected
   js_ast.Identifier emitLibraryName(Library library) {
+    // Avoid adding the dart:_runtime to _imports when our runtime unit tests
+    // import it explicitly. It will always be implicitly imported.
+    if (isSdkInternalRuntime(library)) return runtimeModule;
+
     // It's either one of the libraries in this module, or it's an import.
-    var libraryId = js_ast.TemporaryId(jsLibraryName(library));
     return _libraries[library] ??
-        _imports.putIfAbsent(library, () => libraryId);
+        _imports.putIfAbsent(
+            library, () => js_ast.TemporaryId(jsLibraryName(library)));
   }
 
   /// Emits imports and extension methods into [items].
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index c741457..8401522 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -243,6 +243,7 @@
   fe.IncrementalCompiler incrementalCompiler;
   fe.WorkerInputComponent cachedSdkInput;
   bool recordUsedInputs = argResults['used-inputs-file'] != null;
+  List<Uri> inputSummaries = summaryModules.keys.toList();
   if (useAnalyzer || !useIncrementalCompiler) {
     compilerState = await fe.initializeCompiler(
         oldCompilerState,
@@ -251,7 +252,7 @@
         compileSdk ? null : sourcePathToUri(sdkSummaryPath),
         sourcePathToUri(packageFile),
         sourcePathToUri(librarySpecPath),
-        summaryModules.keys.toList(),
+        inputSummaries,
         DevCompilerTarget(
             TargetFlags(trackWidgetCreation: trackWidgetCreation)),
         fileSystem: fileSystem,
@@ -286,7 +287,7 @@
         compileSdk ? null : sourcePathToUri(sdkSummaryPath),
         sourcePathToUri(packageFile),
         sourcePathToUri(librarySpecPath),
-        summaryModules.keys.toList(),
+        inputSummaries,
         inputDigests,
         DevCompilerTarget(
             TargetFlags(trackWidgetCreation: trackWidgetCreation)),
@@ -299,8 +300,6 @@
         compilerState.workerInputCache[sourcePathToUri(sdkSummaryPath)];
   }
 
-  List<Uri> inputSummaries = compilerState.options.inputSummaries;
-
   // TODO(jmesserly): is there a cleaner way to do this?
   //
   // Ideally we'd manage our own batch compilation caching rather than rely on
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 57b2fe0..db30dd1 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -5044,7 +5044,10 @@
     //      }
     //
     var isTypeError = node.isTypeError;
-    if (!isTypeError && _types.isSubtypeOf(from, to)) return jsFrom;
+    if (!isTypeError &&
+        _types.isSubtypeOf(from, to, SubtypeCheckMode.ignoringNullabilities)) {
+      return jsFrom;
+    }
 
     // All Dart number types map to a JS double.
     if (_typeRep.isNumber(from) && _typeRep.isNumber(to)) {
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 5ae85a5..3bd4a1f 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -64,7 +64,16 @@
       uri.scheme == 'dart' &&
       (uri.path == 'core' || uri.path == '_interceptors');
 
+  /// Returns [true] if [uri] represents a test script has been whitelisted to
+  /// import private platform libraries.
+  ///
+  /// Unit tests for the dart:_runtime library have imports like this. It is
+  /// only allowed from a specific SDK test directory or through the modular
+  /// test framework.
   bool _allowedTestLibrary(Uri uri) {
+    // Multi-root scheme used by modular test framework.
+    if (uri.scheme == 'dev-dart-app') return true;
+
     String scriptName = uri.path;
     return scriptName.contains('tests/compiler/dartdevc_native');
   }
diff --git a/pkg/dev_compiler/test/modular_ddc_suite.dart b/pkg/dev_compiler/test/modular_ddc_suite.dart
index fac2975..4c2a413 100644
--- a/pkg/dev_compiler/test/modular_ddc_suite.dart
+++ b/pkg/dev_compiler/test/modular_ddc_suite.dart
@@ -36,7 +36,17 @@
       IOPipeline([
         DDCStep(),
         RunD8(),
-      ], cacheSharedModules: true, saveIntermediateResultsForTesting: false));
+      ], cacheSharedModules: true));
+
+  // DDC only test suite.
+  await runSuite(
+      sdkRoot.resolve('tests/compiler/dartdevc/modular/'),
+      'tests/compiler/dartdevc/modular',
+      _options,
+      IOPipeline([
+        DDCStep(),
+        RunD8(),
+      ], cacheSharedModules: true));
 }
 
 const sumId = DataId("sum");
diff --git a/pkg/dev_compiler/test/modular_suite.dart b/pkg/dev_compiler/test/modular_suite.dart
index 2442d93..0b4e1e6 100644
--- a/pkg/dev_compiler/test/modular_suite.dart
+++ b/pkg/dev_compiler/test/modular_suite.dart
@@ -81,6 +81,9 @@
       extraArgs = ['--packages-file', '$rootScheme:/.packages'];
     }
 
+    Module sdkModule =
+        module.isSdk ? module : module.dependencies.firstWhere((m) => m.isSdk);
+
     List<String> args = [
       _kernelWorkerScript,
       '--summary-only',
@@ -93,8 +96,14 @@
       ...extraArgs,
       '--output',
       '${toUri(module, dillId)}',
+      if (!module.isSdk) ...[
+        '--dart-sdk-summary',
+        '${toUri(sdkModule, dillId)}',
+        '--exclude-non-sources',
+      ],
       ...(transitiveDependencies
-          .expand((m) => ['--input-linked', '${toUri(m, dillId)}'])),
+          .where((m) => !m.isSdk)
+          .expand((m) => ['--input-summary', '${toUri(m, dillId)}'])),
       ...(sources.expand((String uri) => ['--source', uri])),
       ...(flags.expand((String flag) => ['--enable-experiment', flag])),
     ];
diff --git a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
index 052e2dd..d36bd4a 100644
--- a/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
+++ b/pkg/front_end/lib/src/api_prototype/experimental_flags.dart
@@ -43,7 +43,7 @@
 const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
   ExperimentalFlag.constantUpdate2018: true,
   ExperimentalFlag.controlFlowCollections: true,
-  ExperimentalFlag.extensionMethods: false,
+  ExperimentalFlag.extensionMethods: true,
   ExperimentalFlag.nonNullable: false,
   ExperimentalFlag.setLiterals: true,
   ExperimentalFlag.spreadCollections: true,
diff --git a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
index fd091bb..3618c93 100644
--- a/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
+++ b/pkg/front_end/lib/src/api_prototype/memory_file_system.dart
@@ -26,7 +26,9 @@
   Uri currentDirectory;
 
   MemoryFileSystem(Uri currentDirectory)
-      : currentDirectory = _addTrailingSlash(currentDirectory);
+      : currentDirectory = _addTrailingSlash(currentDirectory) {
+    _directories.add(currentDirectory);
+  }
 
   @override
   MemoryFileSystemEntity entityForUri(Uri uri) {
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index 6c6b5a4..57080d9 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -9,7 +9,7 @@
 
 import 'package:front_end/src/api_prototype/compiler_options.dart';
 
-import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
+import 'package:kernel/kernel.dart' show Component, Library;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -20,23 +20,27 @@
 
 import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
 
-import '../api_prototype/front_end.dart' show CompilerResult;
-
 import '../api_prototype/file_system.dart' show FileSystem;
 
+import '../api_prototype/front_end.dart' show CompilerResult;
+
 import '../base/processed_options.dart' show ProcessedOptions;
 
-import '../fasta/compiler_context.dart' show CompilerContext;
-
-import '../fasta/incremental_compiler.dart' show IncrementalCompiler;
-
 import '../kernel_generator_impl.dart' show generateKernel;
 
-import 'compiler_state.dart'
-    show InitializedCompilerState, WorkerInputComponent, digestsEqual;
+import 'compiler_state.dart' show InitializedCompilerState;
+
+import 'modular_incremental_compilation.dart' as modular
+    show initializeIncrementalCompiler;
+
+export '../api_prototype/compiler_options.dart'
+    show parseExperimentalFlags, parseExperimentalArguments;
 
 export '../api_prototype/diagnostic_message.dart' show DiagnosticMessage;
 
+export '../api_prototype/experimental_flags.dart'
+    show ExperimentalFlag, parseExperimentalFlag;
+
 export '../api_prototype/standard_file_system.dart' show StandardFileSystem;
 
 export '../api_prototype/terminal_color_support.dart'
@@ -48,11 +52,9 @@
 
 export 'compiler_state.dart' show InitializedCompilerState;
 
-import 'util.dart' show equalMaps, equalSets;
-
 /// Initializes the compiler for a modular build.
 ///
-/// Re-uses cached components from [_workerInputCache], and reloads them
+/// Re-uses cached components from [oldState.workerInputCache], and reloads them
 /// as necessary based on [workerInputDigests].
 Future<InitializedCompilerState> initializeIncrementalCompiler(
     InitializedCompilerState oldState,
@@ -67,193 +69,26 @@
     Iterable<String> experiments,
     bool outlineOnly,
     {bool trackNeededDillLibraries: false}) async {
-  final List<int> sdkDigest = workerInputDigests[sdkSummary];
-  if (sdkDigest == null) {
-    throw new StateError("Expected to get digest for $sdkSummary");
-  }
-  IncrementalCompiler incrementalCompiler;
-  CompilerOptions options;
-  ProcessedOptions processedOpts;
-  WorkerInputComponent cachedSdkInput;
-  Map<Uri, WorkerInputComponent> workerInputCache =
-      oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
-  Map<Uri, Uri> workerInputCacheLibs =
-      oldState?.workerInputCacheLibs ?? new Map<Uri, Uri>();
-
-  bool startOver = false;
+  List<Component> outputLoadedInputSummaries =
+      new List<Component>(summaryInputs.length);
   Map<ExperimentalFlag, bool> experimentalFlags = parseExperimentalFlags(
       parseExperimentalArguments(experiments),
       onError: (e) => throw e);
-
-  if (oldState == null ||
-      oldState.incrementalCompiler == null ||
-      oldState.incrementalCompiler.outlineOnly != outlineOnly ||
-      !equalMaps(oldState.options.experimentalFlags, experimentalFlags) ||
-      !equalSets(oldState.tags, tags)) {
-    // No - or immediately not correct - previous state.
-    startOver = true;
-
-    // We'll load a new sdk, anything loaded already will have a wrong root.
-    workerInputCache.clear();
-    workerInputCacheLibs.clear();
-  } else {
-    // We do have a previous state.
-    cachedSdkInput = workerInputCache[sdkSummary];
-    if (cachedSdkInput == null ||
-        !digestsEqual(cachedSdkInput.digest, sdkDigest)) {
-      // The sdk is out of date.
-      startOver = true;
-      // We'll load a new sdk, anything loaded already will have a wrong root.
-      workerInputCache.clear();
-      workerInputCacheLibs.clear();
-    }
-  }
-
-  if (startOver) {
-    // The sdk was either not cached or it has changed.
-    options = new CompilerOptions()
-      ..sdkSummary = sdkSummary
-      ..packagesFileUri = packagesFile
-      ..librariesSpecificationUri = librariesSpecificationUri
-      ..target = target
-      ..fileSystem = fileSystem
-      ..omitPlatform = true
-      ..environmentDefines = const {}
-      ..experimentalFlags = experimentalFlags;
-
-    processedOpts = new ProcessedOptions(options: options);
-    cachedSdkInput = new WorkerInputComponent(
-        sdkDigest, await processedOpts.loadSdkSummary(null));
-    workerInputCache[sdkSummary] = cachedSdkInput;
-    for (Library lib in cachedSdkInput.component.libraries) {
-      if (workerInputCacheLibs.containsKey(lib.importUri)) {
-        throw new StateError("Duplicate sources in sdk.");
-      }
-      workerInputCacheLibs[lib.importUri] = sdkSummary;
-    }
-
-    incrementalCompiler = new IncrementalCompiler.fromComponent(
-        new CompilerContext(processedOpts),
-        cachedSdkInput.component,
-        outlineOnly);
-    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
-  } else {
-    options = oldState.options;
-    processedOpts = oldState.processedOpts;
-    Component sdkComponent = cachedSdkInput.component;
-    // Reset the state of the component.
-    for (Library lib in sdkComponent.libraries) {
-      lib.isExternal = cachedSdkInput.externalLibs.contains(lib.importUri);
-    }
-
-    // Make sure the canonical name root knows about the sdk - otherwise we
-    // won't be able to link to it when loading more outlines.
-    sdkComponent.adoptChildren();
-
-    // TODO(jensj): This is - at least currently - necessary,
-    // although it's not entirely obvious why.
-    // It likely has to do with several outlines containing the same libraries.
-    // Once that stops (and we check for it) we can probably remove this,
-    // and instead only do it when about to reuse an outline in the
-    // 'inputSummaries.add(component);' line further down.
-    for (WorkerInputComponent cachedInput in workerInputCache.values) {
-      cachedInput.component.adoptChildren();
-    }
-
-    // Reuse the incremental compiler, but reset as needed.
-    incrementalCompiler = oldState.incrementalCompiler;
-    incrementalCompiler.invalidateAllSources();
-    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
-    options.packagesFileUri = packagesFile;
-    options.fileSystem = fileSystem;
-    processedOpts.clearFileSystemCache();
-  }
-
-  // Then read all the input summary components.
-  CanonicalName nameRoot = cachedSdkInput.component.root;
-  final List<Component> inputSummaries = <Component>[];
-  Map<Uri, Uri> libraryToInputDill;
-  if (trackNeededDillLibraries) {
-    libraryToInputDill = new Map<Uri, Uri>();
-  }
-  List<Uri> loadFromDill = new List<Uri>();
-  Set<Uri> inputSummariesSet = new Set<Uri>();
-  for (Uri summary in summaryInputs) {
-    inputSummariesSet.add(summary);
-    WorkerInputComponent cachedInput = workerInputCache[summary];
-    List<int> summaryDigest = workerInputDigests[summary];
-    if (summaryDigest == null) {
-      throw new StateError("Expected to get digest for $summary");
-    }
-    if (cachedInput == null ||
-        cachedInput.component.root != nameRoot ||
-        !digestsEqual(cachedInput.digest, summaryDigest)) {
-      // Remove any old libraries from workerInputCacheLibs.
-      Component component = cachedInput?.component;
-      if (component != null) {
-        for (Library lib in component.libraries) {
-          workerInputCacheLibs.remove(lib.importUri);
-        }
-      }
-
-      loadFromDill.add(summary);
-    } else {
-      // Need to reset cached components so they are usable again.
-      Component component = cachedInput.component;
-      for (Library lib in component.libraries) {
-        lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
-        if (trackNeededDillLibraries) {
-          libraryToInputDill[lib.importUri] = summary;
-        }
-      }
-      inputSummaries.add(component);
-    }
-  }
-
-  for (int i = 0; i < loadFromDill.length; i++) {
-    Uri summary = loadFromDill[i];
-    List<int> summaryDigest = workerInputDigests[summary];
-    if (summaryDigest == null) {
-      throw new StateError("Expected to get digest for $summary");
-    }
-    WorkerInputComponent cachedInput = new WorkerInputComponent(
-        summaryDigest,
-        await processedOpts.loadComponent(
-            await fileSystem.entityForUri(summary).readAsBytes(), nameRoot,
-            alwaysCreateNewNamedNodes: true));
-    workerInputCache[summary] = cachedInput;
-    inputSummaries.add(cachedInput.component);
-    for (Library lib in cachedInput.component.libraries) {
-      if (workerInputCacheLibs.containsKey(lib.importUri)) {
-        Uri fromSummary = workerInputCacheLibs[lib.importUri];
-        if (inputSummariesSet.contains(fromSummary)) {
-          throw new StateError(
-              "Asked to load several summaries that contain the same library.");
-        } else {
-          // Library contained in old cached component. Flush that cache.
-          Component component = workerInputCache.remove(fromSummary).component;
-          for (Library lib in component.libraries) {
-            workerInputCacheLibs.remove(lib.importUri);
-          }
-        }
-      } else {
-        workerInputCacheLibs[lib.importUri] = summary;
-      }
-
-      if (trackNeededDillLibraries) {
-        libraryToInputDill[lib.importUri] = summary;
-      }
-    }
-  }
-
-  incrementalCompiler.setModulesToLoadOnNextComputeDelta(inputSummaries);
-
-  return new InitializedCompilerState(options, processedOpts,
-      workerInputCache: workerInputCache,
-      workerInputCacheLibs: workerInputCacheLibs,
-      incrementalCompiler: incrementalCompiler,
-      tags: tags,
-      libraryToInputDill: libraryToInputDill);
+  return modular.initializeIncrementalCompiler(
+      oldState,
+      tags,
+      outputLoadedInputSummaries,
+      sdkSummary,
+      packagesFile,
+      librariesSpecificationUri,
+      summaryInputs,
+      workerInputDigests,
+      target,
+      fileSystem: fileSystem,
+      experimentalFlags: experimentalFlags,
+      outlineOnly: outlineOnly,
+      omitPlatform: true,
+      trackNeededDillLibraries: trackNeededDillLibraries);
 }
 
 Future<InitializedCompilerState> initializeCompiler(
diff --git a/pkg/front_end/lib/src/api_unstable/ddc.dart b/pkg/front_end/lib/src/api_unstable/ddc.dart
index 8885e67..0a5122b 100644
--- a/pkg/front_end/lib/src/api_unstable/ddc.dart
+++ b/pkg/front_end/lib/src/api_unstable/ddc.dart
@@ -6,7 +6,7 @@
 
 import 'package:kernel/class_hierarchy.dart';
 
-import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
+import 'package:kernel/kernel.dart' show Component;
 
 import 'package:kernel/target/targets.dart' show Target;
 
@@ -24,16 +24,14 @@
 
 import '../base/processed_options.dart' show ProcessedOptions;
 
-import '../fasta/compiler_context.dart' show CompilerContext;
-
-import '../fasta/incremental_compiler.dart' show IncrementalCompiler;
-
 import '../kernel_generator_impl.dart' show generateKernel;
 
-import 'compiler_state.dart'
-    show InitializedCompilerState, WorkerInputComponent, digestsEqual;
+import 'compiler_state.dart' show InitializedCompilerState;
 
-import 'util.dart' show equalLists, equalMaps, equalSets;
+import 'modular_incremental_compilation.dart' as modular
+    show initializeIncrementalCompiler;
+
+import 'util.dart' show equalLists, equalMaps;
 
 export '../api_prototype/compiler_options.dart'
     show CompilerOptions, parseExperimentalFlags, parseExperimentalArguments;
@@ -132,6 +130,10 @@
   return new InitializedCompilerState(options, processedOpts);
 }
 
+/// Initializes the compiler for a modular build.
+///
+/// Re-uses cached components from [oldState.workerInputCache], and reloads them
+/// as necessary based on [workerInputDigests].
 Future<InitializedCompilerState> initializeIncrementalCompiler(
     InitializedCompilerState oldState,
     Set<String> tags,
@@ -148,183 +150,25 @@
     Map<ExperimentalFlag, bool> experiments,
     Map<String, String> environmentDefines,
     bool trackNeededDillLibraries: false}) async {
-  inputSummaries.sort((a, b) => a.toString().compareTo(b.toString()));
-
-  IncrementalCompiler incrementalCompiler;
-  WorkerInputComponent cachedSdkInput;
-  CompilerOptions options;
-  ProcessedOptions processedOpts;
-
-  Map<Uri, WorkerInputComponent> workerInputCache =
-      oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
-  Map<Uri, Uri> workerInputCacheLibs =
-      oldState?.workerInputCacheLibs ?? new Map<Uri, Uri>();
-
-  final List<int> sdkDigest = workerInputDigests[sdkSummary];
-  if (sdkDigest == null) {
-    throw new StateError("Expected to get sdk digest at $sdkSummary");
-  }
-
-  cachedSdkInput = workerInputCache[sdkSummary];
-
-  if (oldState == null ||
-      oldState.incrementalCompiler == null ||
-      oldState.options.compileSdk != compileSdk ||
-      cachedSdkInput == null ||
-      !digestsEqual(cachedSdkInput.digest, sdkDigest) ||
-      !equalMaps(oldState.options.experimentalFlags, experiments) ||
-      !equalMaps(oldState.options.environmentDefines, environmentDefines) ||
-      !equalSets(oldState.tags, tags)) {
-    // No - or immediately not correct - previous state.
-    options = new CompilerOptions()
-      ..compileSdk = compileSdk
-      ..sdkRoot = sdkRoot
-      ..sdkSummary = sdkSummary
-      ..packagesFileUri = packagesFile
-      ..inputSummaries = inputSummaries
-      ..librariesSpecificationUri = librariesSpecificationUri
-      ..target = target
-      ..fileSystem = fileSystem ?? StandardFileSystem.instance
-      ..environmentDefines = environmentDefines;
-    if (experiments != null) options.experimentalFlags = experiments;
-
-    // We'll load a new sdk, anything loaded already will have a wrong root.
-    workerInputCache.clear();
-    workerInputCacheLibs.clear();
-
-    processedOpts = new ProcessedOptions(options: options);
-
-    cachedSdkInput = new WorkerInputComponent(
-        sdkDigest, await processedOpts.loadSdkSummary(null));
-    workerInputCache[sdkSummary] = cachedSdkInput;
-    for (Library lib in cachedSdkInput.component.libraries) {
-      if (workerInputCacheLibs.containsKey(lib.importUri)) {
-        throw new StateError("Duplicate sources in sdk.");
-      }
-      workerInputCacheLibs[lib.importUri] = sdkSummary;
-    }
-
-    incrementalCompiler = new IncrementalCompiler.fromComponent(
-        new CompilerContext(processedOpts), cachedSdkInput.component);
-    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
-  } else {
-    options = oldState.options;
-    options.inputSummaries = inputSummaries;
-    processedOpts = oldState.processedOpts;
-
-    for (Library lib in cachedSdkInput.component.libraries) {
-      lib.isExternal = false;
-    }
-    cachedSdkInput.component.adoptChildren();
-    for (WorkerInputComponent cachedInput in workerInputCache.values) {
-      cachedInput.component.adoptChildren();
-    }
-
-    // Reuse the incremental compiler, but reset as needed.
-    incrementalCompiler = oldState.incrementalCompiler;
-    incrementalCompiler.invalidateAllSources();
-    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
-    options.packagesFileUri = packagesFile;
-    options.fileSystem = fileSystem;
-    processedOpts.clearFileSystemCache();
-  }
-  InitializedCompilerState compilerState = new InitializedCompilerState(
-      options, processedOpts,
-      workerInputCache: workerInputCache,
-      incrementalCompiler: incrementalCompiler);
-
-  CanonicalName nameRoot = cachedSdkInput.component.root;
-  Map<Uri, Uri> libraryToInputDill;
-  if (trackNeededDillLibraries) {
-    libraryToInputDill = new Map<Uri, Uri>();
-  }
-  List<int> loadFromDillIndexes = new List<int>();
-
-  // Notice that the ordering of the input summaries matter, so we need to
-  // keep them in order.
-  if (doneInputSummaries.length != inputSummaries.length) {
-    throw new ArgumentError("Invalid length.");
-  }
-  Set<Uri> inputSummariesSet = new Set<Uri>();
-  for (int i = 0; i < inputSummaries.length; i++) {
-    Uri inputSummary = inputSummaries[i];
-    inputSummariesSet.add(inputSummary);
-    WorkerInputComponent cachedInput = workerInputCache[inputSummary];
-    List<int> digest = workerInputDigests[inputSummary];
-    if (digest == null) {
-      throw new StateError("Expected to get digest for $inputSummary");
-    }
-    if (cachedInput == null ||
-        cachedInput.component.root != nameRoot ||
-        !digestsEqual(digest, cachedInput.digest)) {
-      // Remove any old libraries from workerInputCacheLibs.
-      Component component = cachedInput?.component;
-      if (component != null) {
-        for (Library lib in component.libraries) {
-          workerInputCacheLibs.remove(lib.importUri);
-        }
-      }
-
-      loadFromDillIndexes.add(i);
-    } else {
-      // Need to reset cached components so they are usable again.
-      Component component = cachedInput.component;
-      for (Library lib in component.libraries) {
-        lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
-        if (trackNeededDillLibraries) {
-          libraryToInputDill[lib.importUri] = inputSummary;
-        }
-      }
-      component.computeCanonicalNames();
-      doneInputSummaries[i] = component;
-    }
-  }
-
-  for (int i = 0; i < loadFromDillIndexes.length; i++) {
-    int index = loadFromDillIndexes[i];
-    Uri summary = inputSummaries[index];
-    List<int> digest = workerInputDigests[summary];
-    if (digest == null) {
-      throw new StateError("Expected to get digest for $summary");
-    }
-    List<int> bytes = await fileSystem.entityForUri(summary).readAsBytes();
-    WorkerInputComponent cachedInput = new WorkerInputComponent(
-        digest,
-        await compilerState.processedOpts
-            .loadComponent(bytes, nameRoot, alwaysCreateNewNamedNodes: true));
-    workerInputCache[summary] = cachedInput;
-    doneInputSummaries[index] = cachedInput.component;
-    for (Library lib in cachedInput.component.libraries) {
-      if (workerInputCacheLibs.containsKey(lib.importUri)) {
-        Uri fromSummary = workerInputCacheLibs[lib.importUri];
-        if (inputSummariesSet.contains(fromSummary)) {
-          throw new StateError(
-              "Asked to load several summaries that contain the same library.");
-        } else {
-          // Library contained in old cached component. Flush that cache.
-          Component component = workerInputCache.remove(fromSummary).component;
-          for (Library lib in component.libraries) {
-            workerInputCacheLibs.remove(lib.importUri);
-          }
-        }
-      } else {
-        workerInputCacheLibs[lib.importUri] = summary;
-      }
-
-      if (trackNeededDillLibraries) {
-        libraryToInputDill[lib.importUri] = summary;
-      }
-    }
-  }
-
-  incrementalCompiler.setModulesToLoadOnNextComputeDelta(doneInputSummaries);
-
-  return new InitializedCompilerState(options, processedOpts,
-      workerInputCache: workerInputCache,
-      workerInputCacheLibs: workerInputCacheLibs,
-      incrementalCompiler: incrementalCompiler,
-      tags: tags,
-      libraryToInputDill: libraryToInputDill);
+  return modular.initializeIncrementalCompiler(
+      oldState,
+      tags,
+      doneInputSummaries,
+      sdkSummary,
+      packagesFile,
+      librariesSpecificationUri,
+      inputSummaries,
+      workerInputDigests,
+      target,
+      compileSdk: compileSdk,
+      sdkRoot: sdkRoot,
+      fileSystem: fileSystem ?? StandardFileSystem.instance,
+      experimentalFlags: experiments,
+      environmentDefines:
+          environmentDefines ?? const <ExperimentalFlag, bool>{},
+      outlineOnly: false,
+      omitPlatform: false,
+      trackNeededDillLibraries: trackNeededDillLibraries);
 }
 
 Future<DdcResult> compile(InitializedCompilerState compilerState,
diff --git a/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
new file mode 100644
index 0000000..5244f74
--- /dev/null
+++ b/pkg/front_end/lib/src/api_unstable/modular_incremental_compilation.dart
@@ -0,0 +1,243 @@
+// Copyright (c) 2019, 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' show Future;
+
+import 'package:kernel/kernel.dart' show Component, CanonicalName, Library;
+
+import 'package:kernel/target/targets.dart' show Target;
+
+import '../api_prototype/compiler_options.dart' show CompilerOptions;
+
+import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
+
+import '../api_prototype/file_system.dart' show FileSystem;
+
+import '../base/processed_options.dart' show ProcessedOptions;
+
+import '../fasta/compiler_context.dart' show CompilerContext;
+
+import '../fasta/incremental_compiler.dart' show IncrementalCompiler;
+
+import 'compiler_state.dart'
+    show InitializedCompilerState, WorkerInputComponent, digestsEqual;
+
+import 'util.dart' show equalMaps, equalSets;
+
+/// Initializes the compiler for a modular build.
+///
+/// Re-uses cached components from [oldState.workerInputCache], and reloads them
+/// as necessary based on [workerInputDigests].
+///
+/// Notes:
+/// * [outputLoadedInputSummaries] should be given as an empty list of the same
+///   size as the [inputSummaries]. The input summaries are loaded (or taken
+///   from cache) and placed in this list in order, i.e. the `i`-th entry in
+///   [outputLoadedInputSummaries] after this call corresponds to the component
+///   loaded from the `i`-th entry in [inputSummaries].
+Future<InitializedCompilerState> initializeIncrementalCompiler(
+    InitializedCompilerState oldState,
+    Set<String> tags,
+    List<Component> outputLoadedInputSummaries,
+    Uri sdkSummary,
+    Uri packagesFile,
+    Uri librariesSpecificationUri,
+    List<Uri> inputSummaries,
+    Map<Uri, List<int>> workerInputDigests,
+    Target target,
+    {bool compileSdk: false,
+    Uri sdkRoot: null,
+    FileSystem fileSystem,
+    Map<ExperimentalFlag, bool> experimentalFlags,
+    Map<String, String> environmentDefines: const {},
+    bool outlineOnly,
+    bool omitPlatform: false,
+    bool trackNeededDillLibraries: false}) async {
+  final List<int> sdkDigest = workerInputDigests[sdkSummary];
+  if (sdkDigest == null) {
+    throw new StateError("Expected to get digest for $sdkSummary");
+  }
+
+  Map<Uri, WorkerInputComponent> workerInputCache =
+      oldState?.workerInputCache ?? new Map<Uri, WorkerInputComponent>();
+  Map<Uri, Uri> workerInputCacheLibs =
+      oldState?.workerInputCacheLibs ?? new Map<Uri, Uri>();
+
+  WorkerInputComponent cachedSdkInput = workerInputCache[sdkSummary];
+
+  IncrementalCompiler incrementalCompiler;
+  CompilerOptions options;
+  ProcessedOptions processedOpts;
+
+  if (oldState == null ||
+      oldState.incrementalCompiler == null ||
+      oldState.options.compileSdk != compileSdk ||
+      oldState.incrementalCompiler.outlineOnly != outlineOnly ||
+      !equalMaps(oldState.options.experimentalFlags, experimentalFlags) ||
+      !equalMaps(oldState.options.environmentDefines, environmentDefines) ||
+      !equalSets(oldState.tags, tags) ||
+      cachedSdkInput == null ||
+      !digestsEqual(cachedSdkInput.digest, sdkDigest)) {
+    // No - or immediately not correct - previous state.
+    // We'll load a new sdk, anything loaded already will have a wrong root.
+    workerInputCache.clear();
+    workerInputCacheLibs.clear();
+
+    // The sdk was either not cached or it has changed.
+    options = new CompilerOptions()
+      ..compileSdk = compileSdk
+      ..sdkRoot = sdkRoot
+      ..sdkSummary = sdkSummary
+      ..packagesFileUri = packagesFile
+      ..librariesSpecificationUri = librariesSpecificationUri
+      ..target = target
+      ..fileSystem = fileSystem
+      ..omitPlatform = omitPlatform
+      ..environmentDefines = environmentDefines
+      ..experimentalFlags = experimentalFlags;
+
+    processedOpts = new ProcessedOptions(options: options);
+    cachedSdkInput = new WorkerInputComponent(
+        sdkDigest, await processedOpts.loadSdkSummary(null));
+    workerInputCache[sdkSummary] = cachedSdkInput;
+    for (Library lib in cachedSdkInput.component.libraries) {
+      if (workerInputCacheLibs.containsKey(lib.importUri)) {
+        throw new StateError("Duplicate sources in sdk.");
+      }
+      workerInputCacheLibs[lib.importUri] = sdkSummary;
+    }
+
+    incrementalCompiler = new IncrementalCompiler.fromComponent(
+        new CompilerContext(processedOpts),
+        cachedSdkInput.component,
+        outlineOnly);
+    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
+  } else {
+    options = oldState.options;
+    processedOpts = oldState.processedOpts;
+    Component sdkComponent = cachedSdkInput.component;
+    // Reset the state of the component.
+    for (Library lib in sdkComponent.libraries) {
+      lib.isExternal = cachedSdkInput.externalLibs.contains(lib.importUri);
+    }
+
+    // Make sure the canonical name root knows about the sdk - otherwise we
+    // won't be able to link to it when loading more outlines.
+    sdkComponent.adoptChildren();
+
+    // TODO(jensj): This is - at least currently - necessary,
+    // although it's not entirely obvious why.
+    // It likely has to do with several outlines containing the same libraries.
+    // Once that stops (and we check for it) we can probably remove this,
+    // and instead only do it when about to reuse an outline in the
+    // 'inputSummaries.add(component);' line further down.
+    for (WorkerInputComponent cachedInput in workerInputCache.values) {
+      cachedInput.component.adoptChildren();
+    }
+
+    // Reuse the incremental compiler, but reset as needed.
+    incrementalCompiler = oldState.incrementalCompiler;
+    incrementalCompiler.invalidateAllSources();
+    incrementalCompiler.trackNeededDillLibraries = trackNeededDillLibraries;
+    options.packagesFileUri = packagesFile;
+    options.fileSystem = fileSystem;
+    processedOpts.clearFileSystemCache();
+  }
+
+  // Then read all the input summary components.
+  CanonicalName nameRoot = cachedSdkInput.component.root;
+  Map<Uri, Uri> libraryToInputDill;
+  if (trackNeededDillLibraries) {
+    libraryToInputDill = new Map<Uri, Uri>();
+  }
+  List<int> loadFromDillIndexes = new List<int>();
+
+  // Notice that the ordering of the input summaries matter, so we need to
+  // keep them in order.
+  if (outputLoadedInputSummaries.length != inputSummaries.length) {
+    throw new ArgumentError("Invalid length.");
+  }
+  Set<Uri> inputSummariesSet = new Set<Uri>();
+  for (int i = 0; i < inputSummaries.length; i++) {
+    Uri summaryUri = inputSummaries[i];
+    inputSummariesSet.add(summaryUri);
+    WorkerInputComponent cachedInput = workerInputCache[summaryUri];
+    List<int> digest = workerInputDigests[summaryUri];
+    if (digest == null) {
+      throw new StateError("Expected to get digest for $summaryUri");
+    }
+    if (cachedInput == null ||
+        cachedInput.component.root != nameRoot ||
+        !digestsEqual(digest, cachedInput.digest)) {
+      // Remove any old libraries from workerInputCacheLibs.
+      Component component = cachedInput?.component;
+      if (component != null) {
+        for (Library lib in component.libraries) {
+          workerInputCacheLibs.remove(lib.importUri);
+        }
+      }
+
+      loadFromDillIndexes.add(i);
+    } else {
+      // Need to reset cached components so they are usable again.
+      Component component = cachedInput.component;
+      for (Library lib in component.libraries) {
+        lib.isExternal = cachedInput.externalLibs.contains(lib.importUri);
+        if (trackNeededDillLibraries) {
+          libraryToInputDill[lib.importUri] = summaryUri;
+        }
+      }
+      component.computeCanonicalNames(); // this isn't needed, is it?
+      outputLoadedInputSummaries[i] = component;
+    }
+  }
+
+  for (int i = 0; i < loadFromDillIndexes.length; i++) {
+    int index = loadFromDillIndexes[i];
+    Uri summaryUri = inputSummaries[index];
+    List<int> digest = workerInputDigests[summaryUri];
+    if (digest == null) {
+      throw new StateError("Expected to get digest for $summaryUri");
+    }
+
+    List<int> bytes = await fileSystem.entityForUri(summaryUri).readAsBytes();
+    WorkerInputComponent cachedInput = new WorkerInputComponent(
+        digest,
+        await processedOpts.loadComponent(bytes, nameRoot,
+            alwaysCreateNewNamedNodes: true));
+    workerInputCache[summaryUri] = cachedInput;
+    outputLoadedInputSummaries[index] = cachedInput.component;
+    for (Library lib in cachedInput.component.libraries) {
+      if (workerInputCacheLibs.containsKey(lib.importUri)) {
+        Uri fromSummary = workerInputCacheLibs[lib.importUri];
+        if (inputSummariesSet.contains(fromSummary)) {
+          throw new StateError(
+              "Asked to load several summaries that contain the same library.");
+        } else {
+          // Library contained in old cached component. Flush that cache.
+          Component component = workerInputCache.remove(fromSummary).component;
+          for (Library lib in component.libraries) {
+            workerInputCacheLibs.remove(lib.importUri);
+          }
+        }
+      } else {
+        workerInputCacheLibs[lib.importUri] = summaryUri;
+      }
+
+      if (trackNeededDillLibraries) {
+        libraryToInputDill[lib.importUri] = summaryUri;
+      }
+    }
+  }
+
+  incrementalCompiler
+      .setModulesToLoadOnNextComputeDelta(outputLoadedInputSummaries);
+
+  return new InitializedCompilerState(options, processedOpts,
+      workerInputCache: workerInputCache,
+      workerInputCacheLibs: workerInputCacheLibs,
+      incrementalCompiler: incrementalCompiler,
+      tags: tags,
+      libraryToInputDill: libraryToInputDill);
+}
diff --git a/pkg/front_end/lib/src/base/common.dart b/pkg/front_end/lib/src/base/common.dart
new file mode 100644
index 0000000..e511a04
--- /dev/null
+++ b/pkg/front_end/lib/src/base/common.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2019, 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.
+
+/// If `true`, data that would not otherwise be kept is stored for testing.
+bool retainDataForTesting = false;
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index c4a1632..ee0b627 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -51,7 +51,10 @@
 import 'package:kernel/type_algebra.dart' as type_algebra
     show getSubstitutionMap;
 
-import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/type_environment.dart'
+    show SubtypeCheckMode, TypeEnvironment;
+
+import '../../base/common.dart';
 
 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 
@@ -166,6 +169,8 @@
 
   ClassBuilder actualOrigin;
 
+  ClassBuilder patchForTesting;
+
   ClassBuilder(
       List<MetadataBuilder> metadata,
       int modifiers,
@@ -1165,9 +1170,12 @@
     DartType subtype = inParameter ? interfaceType : declaredType;
     DartType supertype = inParameter ? declaredType : interfaceType;
 
-    if (types.isSubtypeOfKernel(subtype, supertype)) {
+    if (types.isSubtypeOfKernel(
+        subtype, supertype, SubtypeCheckMode.ignoringNullabilities)) {
       // No problem--the proper subtyping relation is satisfied.
-    } else if (isCovariant && types.isSubtypeOfKernel(supertype, subtype)) {
+    } else if (isCovariant &&
+        types.isSubtypeOfKernel(
+            supertype, subtype, SubtypeCheckMode.ignoringNullabilities)) {
       // No problem--the overriding parameter is marked "covariant" and has
       // a type which is a subtype of the parameter it overrides.
     } else if (subtype is InvalidType || supertype is InvalidType) {
@@ -1523,6 +1531,9 @@
   void applyPatch(Builder patch) {
     if (patch is ClassBuilder) {
       patch.actualOrigin = this;
+      if (retainDataForTesting) {
+        patchForTesting = patch;
+      }
       // TODO(ahe): Complain if `patch.supertype` isn't null.
       scope.local.forEach((String name, Builder member) {
         Builder memberPatch = patch.scope.local[name];
@@ -1627,7 +1638,8 @@
         DartType typeArgument = typeArguments[i];
         // Check whether the [typeArgument] respects the bounds of
         // [typeParameter].
-        if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound)) {
+        if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound,
+            SubtypeCheckMode.ignoringNullabilities)) {
           addProblem(
               templateRedirectingFactoryIncompatibleTypeArgument.withArguments(
                   typeArgument, typeParameterBound),
@@ -1685,7 +1697,8 @@
     if (redirecteeType == null) return;
 
     // Check whether [redirecteeType] <: [factoryType].
-    if (!typeEnvironment.isSubtypeOf(redirecteeType, factoryType)) {
+    if (!typeEnvironment.isSubtypeOf(
+        redirecteeType, factoryType, SubtypeCheckMode.ignoringNullabilities)) {
       addProblem(
           templateIncompatibleRedirecteeFunctionType.withArguments(
               redirecteeType, factoryType),
diff --git a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
index f591207..2f1777b 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
@@ -156,4 +156,10 @@
     newTypes.add(newType);
     return newType;
   }
+
+  FunctionTypeBuilder withNullabilityBuilder(
+      NullabilityBuilder nullabilityBuilder) {
+    return new FunctionTypeBuilder(
+        returnType, typeVariables, formals, nullabilityBuilder);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart b/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
index a0f7861..2ecb4a6 100644
--- a/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
@@ -4,7 +4,8 @@
 
 library fasta.mixin_application_builder;
 
-import 'builder.dart' show LibraryBuilder, TypeBuilder, TypeVariableBuilder;
+import 'builder.dart'
+    show LibraryBuilder, NullabilityBuilder, TypeBuilder, TypeVariableBuilder;
 
 import 'package:kernel/ast.dart' show InterfaceType, Supertype;
 
@@ -23,6 +24,10 @@
 
   String get name => null;
 
+  NullabilityBuilder get nullabilityBuilder {
+    return unsupported("nullabilityBuilder", -1, null);
+  }
+
   String get debugName => "MixinApplicationBuilder";
 
   StringBuffer printOn(StringBuffer buffer) {
@@ -61,6 +66,12 @@
     return unsupported("buildInvalidType", message.charOffset, message.uri);
   }
 
+  @override
+  MixinApplicationBuilder withNullabilityBuilder(
+      NullabilityBuilder nullabilityBuilder) {
+    return unsupported("withNullabilityBuilder", -1, null);
+  }
+
   MixinApplicationBuilder clone(List<TypeBuilder> newTypes) {
     int charOffset = -1; // TODO(dmitryas): Provide these.
     Uri fileUri = null; // TODO(dmitryas): Provide these.
diff --git a/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart b/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
index 6357975..592ecf2 100644
--- a/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/modifier_builder.dart
@@ -74,5 +74,6 @@
     return buffer..write(name ?? fullNameForErrors);
   }
 
-  String toString() => "$debugName(${printOn(new StringBuffer())})";
+  String toString() =>
+      "${isPatch ? 'patch ' : ''}$debugName(${printOn(new StringBuffer())})";
 }
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 38a57ae..a956d76 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -296,4 +296,10 @@
     newTypes.add(newType);
     return newType;
   }
+
+  NamedTypeBuilder withNullabilityBuilder(
+      NullabilityBuilder nullabilityBuilder) {
+    return new NamedTypeBuilder(name, nullabilityBuilder, arguments)
+      ..bind(declaration);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
index d818e4d..0335f23 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -11,6 +11,8 @@
 
 import 'package:kernel/type_algebra.dart';
 
+import '../../base/common.dart';
+
 import 'builder.dart'
     show
         Builder,
@@ -459,6 +461,7 @@
   final Procedure _procedure;
   final int charOpenParenOffset;
   final ProcedureKind kind;
+  ProcedureBuilder patchForTesting;
 
   AsyncMarker actualAsyncModifier = AsyncMarker.Sync;
 
@@ -553,8 +556,8 @@
       _procedure.isConst = isConst;
       if (isExtensionMethod) {
         ExtensionBuilder extensionBuilder = parent;
-        procedure.isExtensionMember = true;
-        procedure.isStatic = true;
+        _procedure.isExtensionMember = true;
+        _procedure.isStatic = true;
         String kindInfix = '';
         if (isExtensionInstanceMember) {
           // Instance getter and setter are converted to methods so we use an
@@ -574,18 +577,18 @@
               throw new UnsupportedError(
                   'Unexpected extension method kind ${kind}');
           }
-          procedure.kind = ProcedureKind.Method;
+          _procedure.kind = ProcedureKind.Method;
         }
-        procedure.name = new Name(
+        _procedure.name = new Name(
             '${extensionBuilder.name}|${kindInfix}${name}',
             libraryBuilder.library);
       } else {
         _procedure.isStatic = isStatic;
         _procedure.name = new Name(name, libraryBuilder.library);
       }
-    }
-    if (extensionTearOff != null) {
-      _buildExtensionTearOff(libraryBuilder, parent);
+      if (extensionTearOff != null) {
+        _buildExtensionTearOff(libraryBuilder, parent);
+      }
     }
     return _procedure;
   }
@@ -698,7 +701,7 @@
 
     Statement closureBody = new ReturnStatement(
         new StaticInvocation(
-            procedure,
+            _procedure,
             new Arguments(closurePositionalArguments,
                 types: typeArguments, named: closureNamedArguments))
           ..fileOffset = fileOffset)
@@ -709,10 +712,10 @@
         typeParameters: closureTypeParameters,
         positionalParameters: closurePositionalParameters,
         namedParameters: closureNamedParameters,
-        requiredParameterCount: procedure.function.requiredParameterCount - 1,
+        requiredParameterCount: _procedure.function.requiredParameterCount - 1,
         returnType: closureReturnType,
-        asyncMarker: procedure.function.asyncMarker,
-        dartAsyncMarker: procedure.function.dartAsyncMarker))
+        asyncMarker: _procedure.function.asyncMarker,
+        dartAsyncMarker: _procedure.function.dartAsyncMarker))
       ..fileOffset = fileOffset;
 
     _extensionTearOff
@@ -783,6 +786,9 @@
     if (patch is ProcedureBuilder) {
       if (checkPatch(patch)) {
         patch.actualOrigin = this;
+        if (retainDataForTesting) {
+          patchForTesting = patch;
+        }
       }
     } else {
       reportPatchMismatch(patch);
@@ -807,6 +813,8 @@
   @override
   ConstructorBuilder actualOrigin;
 
+  ConstructorBuilder patchForTesting;
+
   Constructor get actualConstructor => _constructor;
 
   ConstructorBuilder(
@@ -998,6 +1006,9 @@
     if (patch is ConstructorBuilder) {
       if (checkPatch(patch)) {
         patch.actualOrigin = this;
+        if (retainDataForTesting) {
+          patchForTesting = patch;
+        }
       }
     } else {
       reportPatchMismatch(patch);
diff --git a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
index f07de9d..7a7bc4c 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
@@ -150,10 +150,9 @@
   /// [arguments] have already been built.
   DartType buildTypesWithBuiltArguments(LibraryBuilder library,
       Nullability nullability, List<DartType> arguments) {
-    // TODO(dmitryas): Use [nullability].
     DartType thisType = buildThisType(library);
     if (const DynamicType() == thisType) return thisType;
-    FunctionType result = thisType;
+    FunctionType result = thisType.withNullability(nullability);
     if (typedef.typeParameters.isEmpty && arguments == null) return result;
     Map<TypeParameter, DartType> substitution = <TypeParameter, DartType>{};
     for (int i = 0; i < typedef.typeParameters.length; i++) {
@@ -209,8 +208,9 @@
       NullabilityBuilder nullabilityBuilder, List<TypeBuilder> arguments) {
     DartType thisType = buildThisType(library);
     if (thisType is InvalidType) return thisType;
-    FunctionType result = thisType;
-    if (typedef.typeParameters.isEmpty && arguments == null) return result;
+    if (typedef.typeParameters.isEmpty && arguments == null) {
+      return thisType.withNullability(nullabilityBuilder.build(library));
+    }
     // Otherwise, substitute.
     return buildTypesWithBuiltArguments(
         library,
diff --git a/pkg/front_end/lib/src/fasta/builder/type_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
index 93b1ade..ae2428b 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
@@ -10,6 +10,7 @@
 
 import '../scope.dart';
 import 'library_builder.dart';
+import 'nullability_builder.dart';
 import 'type_declaration_builder.dart';
 import 'type_variable_builder.dart';
 
@@ -32,6 +33,8 @@
   /// May return null, for example, for mixin applications.
   Object get name;
 
+  NullabilityBuilder get nullabilityBuilder;
+
   String get debugName;
 
   StringBuffer printOn(StringBuffer buffer);
@@ -65,4 +68,6 @@
 
   Supertype buildMixedInType(
       LibraryBuilder library, int charOffset, Uri fileUri);
+
+  TypeBuilder withNullabilityBuilder(NullabilityBuilder nullabilityBuilder);
 }
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart
index b46cd36..d45a8c7 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_extension_member_builder.dart
@@ -26,7 +26,7 @@
   bool get isStatic => _descriptor.isStatic;
 
   @override
-  bool get isExternal => _descriptor.isExternal;
+  bool get isExternal => member.isExternal;
 
   @override
   Procedure get procedure {
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 ad6ebd4..34eb285 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -161,12 +161,9 @@
         DartType _type,
         DartType
             _type2)> templateArgumentTypeNotAssignable = const Template<
-        Message Function(DartType _type,
-            DartType _type2)>(
+        Message Function(DartType _type, DartType _type2)>(
     messageTemplate:
         r"""The argument type '#type' can't be assigned to the parameter type '#type2'.""",
-    tipTemplate:
-        r"""Try changing the type of the parameter, or casting the argument to '#type2'.""",
     withArguments: _withArgumentsArgumentTypeNotAssignable);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -188,7 +185,6 @@
       message:
           """The argument type '${type}' can't be assigned to the parameter type '${type2}'.""" +
               labeler.originMessages,
-      tip: """Try changing the type of the parameter, or casting the argument to '${type2}'.""",
       arguments: {'type': _type, 'type2': _type2});
 }
 
@@ -422,7 +418,6 @@
     const Template<Message Function(Token token)>(
         messageTemplate:
             r"""The built-in identifier '#lexeme' can't be used as a type.""",
-        tipTemplate: r"""Try correcting the name to match an existing type.""",
         withArguments: _withArgumentsBuiltInIdentifierAsType);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -437,7 +432,6 @@
   return new Message(codeBuiltInIdentifierAsType,
       message:
           """The built-in identifier '${lexeme}' can't be used as a type.""",
-      tip: """Try correcting the name to match an existing type.""",
       arguments: {'token': token});
 }
 
@@ -770,7 +764,7 @@
     "CantUsePrefixWithNullAware",
     analyzerCodes: <String>["PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT"],
     message: r"""A prefix can't be used with null-aware operators.""",
-    tip: r"""It should be safe to remove the '?' as a prefix is never null.""");
+    tip: r"""Try replacing '?.' with '.'""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeCatchSyntax = messageCatchSyntax;
@@ -1771,7 +1765,7 @@
         Message Function(String name)>(
     messageTemplate: r"""The const variable '#name' must be initialized.""",
     tipTemplate:
-        r"""Try adding an initializer ('= <expression>') to the declaration.""",
+        r"""Try adding an initializer ('= expression') to the declaration.""",
     withArguments: _withArgumentsConstFieldWithoutInitializer);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -1786,8 +1780,7 @@
   name = demangleMixinApplicationName(name);
   return new Message(codeConstFieldWithoutInitializer,
       message: """The const variable '${name}' must be initialized.""",
-      tip:
-          """Try adding an initializer ('= <expression>') to the declaration.""",
+      tip: """Try adding an initializer ('= expression') to the declaration.""",
       arguments: {'name': name});
 }
 
@@ -2909,8 +2902,8 @@
     "EqualityCannotBeEqualityOperand",
     index: 1,
     message:
-        r"""An equality expression can't be an operand of another equality expression.""",
-    tip: r"""Try re-writing the expression.""");
+        r"""A comparison expression can't be an operand of another comparison expression.""",
+    tip: r"""Try putting parentheses around one of the comparisons.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String string)> templateExpectedAfterButGot =
@@ -3469,6 +3462,32 @@
     tip: r"""Try removing the field declaration or making it a static field""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateExtensionMemberConflictsWithObjectMember =
+    const Template<Message Function(String name)>(
+        messageTemplate:
+            r"""This extension member conflicts with Object member '#name'.""",
+        withArguments: _withArgumentsExtensionMemberConflictsWithObjectMember);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)>
+    codeExtensionMemberConflictsWithObjectMember =
+    const Code<Message Function(String name)>(
+  "ExtensionMemberConflictsWithObjectMember",
+  templateExtensionMemberConflictsWithObjectMember,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsExtensionMemberConflictsWithObjectMember(String name) {
+  if (name.isEmpty) throw 'No name provided';
+  name = demangleMixinApplicationName(name);
+  return new Message(codeExtensionMemberConflictsWithObjectMember,
+      message:
+          """This extension member conflicts with Object member '${name}'.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeExternalClass = messageExternalClass;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -3539,7 +3558,8 @@
 const MessageCode messageExternalField = const MessageCode("ExternalField",
     index: 50,
     message: r"""Fields can't be declared to be 'external'.""",
-    tip: r"""Try removing the keyword 'external'.""");
+    tip:
+        r"""Try removing the keyword 'external', or replacing the field by an external getter and/or setter.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeExternalMethodWithBody = messageExternalMethodWithBody;
@@ -4103,7 +4123,7 @@
 const MessageCode messageFieldInitializedOutsideDeclaringClass = const MessageCode(
     "FieldInitializedOutsideDeclaringClass",
     index: 88,
-    message: r"""A field can only be initialized in it's declaring class""",
+    message: r"""A field can only be initialized in its declaring class""",
     tip:
         r"""Try passing a value into the superclass constructor, or moving the initialization into the constructor body.""");
 
@@ -4206,7 +4226,7 @@
         Message Function(String name)>(
     messageTemplate: r"""The final variable '#name' must be initialized.""",
     tipTemplate:
-        r"""Try adding an initializer ('= <expression>') to the declaration.""",
+        r"""Try adding an initializer ('= expression') to the declaration.""",
     withArguments: _withArgumentsFinalFieldWithoutInitializer);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -4221,8 +4241,7 @@
   name = demangleMixinApplicationName(name);
   return new Message(codeFinalFieldWithoutInitializer,
       message: """The final variable '${name}' must be initialized.""",
-      tip:
-          """Try adding an initializer ('= <expression>') to the declaration.""",
+      tip: """Try adding an initializer ('= expression') to the declaration.""",
       arguments: {'name': name});
 }
 
@@ -4423,7 +4442,7 @@
     templateGenericFunctionTypeInferredAsActualTypeArgument =
     const Template<Message Function(DartType _type)>(
         messageTemplate:
-            r"""Unexpected generic function type '#type' inferred as a type argument.""",
+            r"""Generic function type '#type' inferred as a type argument.""",
         tipTemplate:
             r"""Try providing a non-generic function type explicitly.""",
         withArguments:
@@ -4445,7 +4464,7 @@
   String type = typeParts.join();
   return new Message(codeGenericFunctionTypeInferredAsActualTypeArgument,
       message:
-          """Unexpected generic function type '${type}' inferred as a type argument.""" +
+          """Generic function type '${type}' inferred as a type argument.""" +
               labeler.originMessages,
       tip: """Try providing a non-generic function type explicitly.""",
       arguments: {'type': _type});
@@ -4460,7 +4479,7 @@
     const MessageCode("GenericFunctionTypeUsedAsActualTypeArgument",
         analyzerCodes: <String>["GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT"],
         message:
-            r"""Unexpected generic function type found in a type argument.""",
+            r"""A generic function type can't be used as a type argument.""",
         tip: r"""Try using a non-generic function type.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -6145,8 +6164,6 @@
         Message Function(DartType _type, DartType _type2)>(
     messageTemplate:
         r"""A value of type '#type' can't be assigned to a variable of type '#type2'.""",
-    tipTemplate:
-        r"""Try changing the type of the left hand side, or casting the right hand side to '#type2'.""",
     withArguments: _withArgumentsInvalidAssignment);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -6167,7 +6184,6 @@
       message:
           """A value of type '${type}' can't be assigned to a variable of type '${type2}'.""" +
               labeler.originMessages,
-      tip: """Try changing the type of the left hand side, or casting the right hand side to '${type2}'.""",
       arguments: {'type': _type, 'type2': _type2});
 }
 
@@ -6659,8 +6675,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageInvalidVoid = const MessageCode("InvalidVoid",
     analyzerCodes: <String>["EXPECTED_TYPE_NAME"],
-    message:
-        r"""Type 'void' can't be used here because it isn't a return type.""",
+    message: r"""Type 'void' can't be used here.""",
     tip:
         r"""Try removing 'void' keyword or replace it with 'var', 'final', or a type.""");
 
@@ -6935,7 +6950,7 @@
 const MessageCode messageMissingAssignableSelector = const MessageCode(
     "MissingAssignableSelector",
     index: 35,
-    message: r"""Missing selector such as '.<identifier>' or '[0]'.""",
+    message: r"""Missing selector such as '.identifier' or '[0]'.""",
     tip: r"""Try adding a selector.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -7162,7 +7177,7 @@
     "MissingPrefixInDeferredImport",
     index: 30,
     message: r"""Deferred imports should have a prefix.""",
-    tip: r"""Try adding a prefix to the import.""");
+    tip: r"""Try adding a prefix to the import by adding an 'as' clause.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeMissingTypedefParameters = messageMissingTypedefParameters;
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 43af7e5..61e208b 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -9,11 +9,9 @@
 import 'package:front_end/src/fasta/dill/dill_class_builder.dart'
     show DillClassBuilder;
 
-import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;
-
 import 'package:kernel/binary/ast_from_binary.dart'
     show
-        BinaryBuilder,
+        BinaryBuilderWithMetadata,
         CanonicalNameError,
         CanonicalNameSdkError,
         InvalidKernelVersionError;
@@ -730,7 +728,7 @@
     if (summaryBytes != null) {
       ticker.logMs("Read ${c.options.sdkSummary}");
       data.component = c.options.target.configureComponent(new Component());
-      new BinaryBuilder(summaryBytes,
+      new BinaryBuilderWithMetadata(summaryBytes,
               disableLazyReading: false, disableLazyClassReading: true)
           .readComponent(data.component);
       ticker.logMs("Deserialized ${c.options.sdkSummary}");
@@ -755,7 +753,8 @@
 
         // We're going to output all we read here so lazy loading it
         // doesn't make sense.
-        new BinaryBuilder(initializationBytes, disableLazyReading: true)
+        new BinaryBuilderWithMetadata(initializationBytes,
+                disableLazyReading: true)
             .readComponent(data.component, checkCanonicalNames: true);
 
         // Check the any package-urls still point to the same file
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 656b1ae..6d6ca44 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -7,6 +7,7 @@
 import 'dart:core' hide MapEntry;
 
 import 'package:kernel/ast.dart';
+import 'package:kernel/type_environment.dart';
 
 import '../builder/declaration_builder.dart';
 
@@ -826,59 +827,9 @@
           body, transformSetLiterals, transformCollections);
     }
 
-    // For async, async*, and sync* functions with declared return types, we
-    // need to determine whether those types are valid.
     if (builder.returnType != null) {
-      DartType returnType = builder.function.returnType;
-      // We use the same trick in each case below. For example to decide whether
-      // Future<T> <: [returnType] for every T, we rely on Future<Bot> and
-      // transitivity of the subtyping relation because Future<Bot> <: Future<T>
-      // for every T.
-
-      // We use [problem == null] to signal success.
-      Message problem;
-      switch (asyncModifier) {
-        case AsyncMarker.Async:
-          DartType futureBottomType = libraryBuilder.loader.futureOfBottom;
-          if (!typeEnvironment.isSubtypeOf(futureBottomType, returnType)) {
-            problem = fasta.messageIllegalAsyncReturnType;
-          }
-          break;
-
-        case AsyncMarker.AsyncStar:
-          DartType streamBottomType = libraryBuilder.loader.streamOfBottom;
-          if (returnType is VoidType) {
-            problem = fasta.messageIllegalAsyncGeneratorVoidReturnType;
-          } else if (!typeEnvironment.isSubtypeOf(
-              streamBottomType, returnType)) {
-            problem = fasta.messageIllegalAsyncGeneratorReturnType;
-          }
-          break;
-
-        case AsyncMarker.SyncStar:
-          DartType iterableBottomType = libraryBuilder.loader.iterableOfBottom;
-          if (returnType is VoidType) {
-            problem = fasta.messageIllegalSyncGeneratorVoidReturnType;
-          } else if (!typeEnvironment.isSubtypeOf(
-              iterableBottomType, returnType)) {
-            problem = fasta.messageIllegalSyncGeneratorReturnType;
-          }
-          break;
-
-        case AsyncMarker.Sync:
-          break; // skip
-        case AsyncMarker.SyncYielding:
-          unexpected("async, async*, sync, or sync*", "$asyncModifier",
-              member.charOffset, uri);
-          break;
-      }
-
-      if (problem != null) {
-        // TODO(hillerstrom): once types get annotated with location
-        // information, we can improve the quality of the error message by
-        // using the offset of [returnType] (and the length of its name).
-        addProblem(problem, member.charOffset, member.name.length);
-      }
+      checkAsyncReturnType(asyncModifier, builder.function.returnType,
+          member.charOffset, member.name.length);
     }
 
     if (builder.kind == ProcedureKind.Setter) {
@@ -947,6 +898,62 @@
     finishVariableMetadata();
   }
 
+  void checkAsyncReturnType(AsyncMarker asyncModifier, DartType returnType,
+      int charOffset, int length) {
+    // For async, async*, and sync* functions with declared return types, we
+    // need to determine whether those types are valid.
+    // We use the same trick in each case below. For example to decide whether
+    // Future<T> <: [returnType] for every T, we rely on Future<Bot> and
+    // transitivity of the subtyping relation because Future<Bot> <: Future<T>
+    // for every T.
+
+    // We use [problem == null] to signal success.
+    Message problem;
+    switch (asyncModifier) {
+      case AsyncMarker.Async:
+        DartType futureBottomType = libraryBuilder.loader.futureOfBottom;
+        if (!typeEnvironment.isSubtypeOf(futureBottomType, returnType,
+            SubtypeCheckMode.ignoringNullabilities)) {
+          problem = fasta.messageIllegalAsyncReturnType;
+        }
+        break;
+
+      case AsyncMarker.AsyncStar:
+        DartType streamBottomType = libraryBuilder.loader.streamOfBottom;
+        if (returnType is VoidType) {
+          problem = fasta.messageIllegalAsyncGeneratorVoidReturnType;
+        } else if (!typeEnvironment.isSubtypeOf(streamBottomType, returnType,
+            SubtypeCheckMode.ignoringNullabilities)) {
+          problem = fasta.messageIllegalAsyncGeneratorReturnType;
+        }
+        break;
+
+      case AsyncMarker.SyncStar:
+        DartType iterableBottomType = libraryBuilder.loader.iterableOfBottom;
+        if (returnType is VoidType) {
+          problem = fasta.messageIllegalSyncGeneratorVoidReturnType;
+        } else if (!typeEnvironment.isSubtypeOf(iterableBottomType, returnType,
+            SubtypeCheckMode.ignoringNullabilities)) {
+          problem = fasta.messageIllegalSyncGeneratorReturnType;
+        }
+        break;
+
+      case AsyncMarker.Sync:
+        break; // skip
+      case AsyncMarker.SyncYielding:
+        unexpected("async, async*, sync, or sync*", "$asyncModifier",
+            member.charOffset, uri);
+        break;
+    }
+
+    if (problem != null) {
+      // TODO(hillerstrom): once types get annotated with location
+      // information, we can improve the quality of the error message by
+      // using the offset of [returnType] (and the length of its name).
+      addProblem(problem, charOffset, length);
+    }
+  }
+
   /// Ensure that the containing library of the [member] has been loaded.
   ///
   /// This is for instance important for lazy dill library builders where this
@@ -4070,6 +4077,10 @@
       }
       FunctionDeclarationImpl.setHasImplicitReturnType(
           declaration, hasImplicitReturnType);
+      if (!hasImplicitReturnType) {
+        checkAsyncReturnType(asyncModifier, function.returnType,
+            variable.fileOffset, variable.name.length);
+      }
 
       variable.type = function.functionType;
       if (isFunctionExpression) {
@@ -5036,7 +5047,8 @@
           ..fileOffset = assignmentOffset;
       } else {
         if (formalType != null &&
-            !typeEnvironment.isSubtypeOf(formalType, builder.field.type)) {
+            !typeEnvironment.isSubtypeOf(formalType, builder.field.type,
+                SubtypeCheckMode.ignoringNullabilities)) {
           libraryBuilder.addProblem(
               fasta.templateInitializingFormalTypeMismatch
                   .withArguments(name, formalType, builder.field.type),
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 991fa4e..c588cd2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -26,6 +26,7 @@
 import 'package:kernel/core_types.dart' show CoreTypes;
 
 import 'package:kernel/type_algebra.dart' show Substitution;
+import 'package:kernel/type_environment.dart';
 
 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
 
@@ -1997,8 +1998,9 @@
   }
 
   @override
-  bool isSubtypeOf(DartType subtype, DartType supertype) {
-    return hierarchy.types.isSubtypeOfKernel(subtype, supertype);
+  bool isSubtypeOf(
+      DartType subtype, DartType supertype, SubtypeCheckMode mode) {
+    return hierarchy.types.isSubtypeOfKernel(subtype, supertype, mode);
   }
 
   @override
@@ -2095,7 +2097,8 @@
             if (a.hadTypesInferred) {
               if (b.isSetter &&
                   (!impliesSetter(a) ||
-                      hierarchy.types.isSubtypeOfKernel(type, a.field.type))) {
+                      hierarchy.types.isSubtypeOfKernel(type, a.field.type,
+                          SubtypeCheckMode.ignoringNullabilities))) {
                 type = a.field.type;
               } else {
                 reportCantInferFieldType(classBuilder, a);
@@ -2263,9 +2266,11 @@
 
   bool isMoreSpecific(ClassHierarchyBuilder hierarchy, DartType a, DartType b) {
     if (isSetter) {
-      return hierarchy.types.isSubtypeOfKernel(b, a);
+      return hierarchy.types
+          .isSubtypeOfKernel(b, a, SubtypeCheckMode.ignoringNullabilities);
     } else {
-      return hierarchy.types.isSubtypeOfKernel(a, b);
+      return hierarchy.types
+          .isSubtypeOfKernel(a, b, SubtypeCheckMode.ignoringNullabilities);
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 0821f5e..f477cee 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -1858,7 +1858,8 @@
         }
       }
     }
-    return typeEnvironment.isSubtypeOf(constantType, type);
+    return typeEnvironment.isSubtypeOf(
+        constantType, type, SubtypeCheckMode.ignoringNullabilities);
   }
 
   Constant ensureIsSubtype(Constant constant, DartType type, TreeNode node) {
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 e1f4092..2a22a37 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -1961,10 +1961,12 @@
       List<DartType> explicitTypeArguments,
       int extensionTypeParameterCount,
       {bool isNullAware}) {
+    assert(getterBuilder != null || setterBuilder != null);
     String targetName;
     Procedure readTarget;
     Procedure invokeTarget;
     if (getterBuilder != null) {
+      assert(!getterBuilder.isStatic);
       if (getterBuilder is AccessErrorBuilder) {
         AccessErrorBuilder error = getterBuilder;
         getterBuilder = error.builder;
@@ -1989,12 +1991,21 @@
       }
     }
     Procedure writeTarget;
-    if (setterBuilder is AccessErrorBuilder) {
-      targetName ??= setterBuilder.name;
-    } else if (setterBuilder != null && setterBuilder.isSetter) {
-      MemberBuilder memberBuilder = setterBuilder;
-      writeTarget = memberBuilder.member;
-      targetName ??= memberBuilder.name;
+    if (setterBuilder != null) {
+      assert(!setterBuilder.isStatic);
+      if (setterBuilder is AccessErrorBuilder) {
+        targetName ??= setterBuilder.name;
+      } else if (setterBuilder.isSetter) {
+        MemberBuilder memberBuilder = setterBuilder;
+        writeTarget = memberBuilder.member;
+        targetName ??= memberBuilder.name;
+      } else {
+        return unhandled(
+            "${setterBuilder.runtimeType}",
+            "InstanceExtensionAccessGenerator.fromBuilder",
+            offsetForToken(token),
+            helper.uri);
+      }
     }
     return new ExplicitExtensionInstanceAccessGenerator(
         helper,
@@ -2554,10 +2565,16 @@
     return _makeInvalidRead();
   }
 
-  Generator _createInstanceAccess(Name name, {bool isNullAware}) {
+  Generator _createInstanceAccess(Token token, Name name, {bool isNullAware}) {
     Builder getter = extensionBuilder.lookupLocalMember(name.name);
+    if (getter != null && getter.isStatic) {
+      getter = null;
+    }
     Builder setter =
         extensionBuilder.lookupLocalMember(name.name, setter: true);
+    if (setter != null && setter.isStatic) {
+      setter = null;
+    }
     if (getter == null && setter == null) {
       return new UnresolvedNameGenerator(_helper, token, name);
     }
@@ -2580,7 +2597,7 @@
           messageNotAConstantExpression, fileOffset, token.length);
     }
     Generator generator =
-        _createInstanceAccess(send.name, isNullAware: isNullAware);
+        _createInstanceAccess(send.token, send.name, isNullAware: isNullAware);
     if (send.arguments != null) {
       return generator.doInvocation(offsetForToken(send.token), send.arguments);
     } else {
@@ -2590,7 +2607,8 @@
 
   @override
   doInvocation(int offset, Arguments arguments) {
-    Generator generator = _createInstanceAccess(callName, isNullAware: false);
+    Generator generator =
+        _createInstanceAccess(token, callName, isNullAware: false);
     return generator.doInvocation(offset, arguments);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index 3c7ea2e..99e4ad8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -5,7 +5,7 @@
 library fasta.implicit_type;
 
 import 'package:kernel/ast.dart'
-    show DartType, DartTypeVisitor, DartTypeVisitor1, Visitor;
+    show DartType, DartTypeVisitor, DartTypeVisitor1, Nullability, Visitor;
 
 import '../../scanner/token.dart' show Token;
 
@@ -18,11 +18,11 @@
   Token initializerToken;
   bool isStarted = false;
 
-  get nullability =>
-      unsupported("nullability", member.charOffset, member.fileUri);
-
   ImplicitFieldType(this.member, this.initializerToken);
 
+  Nullability get nullability =>
+      unsupported("nullability", member.charOffset, member.fileUri);
+
   R accept<R>(DartTypeVisitor<R> v) {
     throw unsupported("accept", member.charOffset, member.fileUri);
   }
@@ -34,4 +34,8 @@
   visitChildren(Visitor<Object> v) {
     unsupported("visitChildren", member.charOffset, member.fileUri);
   }
+
+  ImplicitFieldType withNullability(Nullability nullability) {
+    return unsupported("withNullability", member.charOffset, member.fileUri);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
index 6cb9d18..e9a98e5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_type_argument.dart
@@ -5,7 +5,7 @@
 library fasta.implicit_type_argument;
 
 import 'package:kernel/ast.dart'
-    show DartType, DartTypeVisitor, DartTypeVisitor1, Visitor;
+    show DartType, DartTypeVisitor, DartTypeVisitor1, Nullability, Visitor;
 
 import '../problems.dart' show unhandled, unsupported;
 
@@ -18,7 +18,7 @@
   const ImplicitTypeArgument();
 
   @override
-  get nullability => unsupported("nullability", -1, null);
+  Nullability get nullability => unsupported("nullability", -1, null);
 
   @override
   R accept<R>(DartTypeVisitor<R> v) {
@@ -34,4 +34,9 @@
   visitChildren(Visitor<Object> v) {
     unhandled("$runtimeType", "${v.runtimeType}", -1, null);
   }
+
+  @override
+  ImplicitTypeArgument withNullability(Nullability nullability) {
+    return unsupported("withNullability", -1, null);
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 816cc1e..c1b4dc0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -366,12 +366,9 @@
     }
     bool hasExplicitTypeArguments =
         getExplicitTypeArguments(node.arguments) != null;
-    DartType inferredType = inferrer.inferInvocation(
-        typeContext,
-        node.fileOffset,
-        node.target.function.thisFunctionType,
-        computeConstructorReturnType(node.target),
-        node.arguments,
+    DartType inferredType = inferrer.inferInvocation(typeContext,
+        node.fileOffset, node.target.function.thisFunctionType, node.arguments,
+        returnType: computeConstructorReturnType(node.target),
         isConst: node.isConst);
     if (!inferrer.isTopLevel) {
       SourceLibraryBuilder library = inferrer.library;
@@ -396,8 +393,8 @@
         : new FunctionType([], const DynamicType());
     bool hadExplicitTypeArguments =
         getExplicitTypeArguments(node.arguments) != null;
-    DartType inferredType = inferrer.inferInvocation(typeContext,
-        node.fileOffset, calleeType, calleeType.returnType, node.arguments);
+    DartType inferredType = inferrer.inferInvocation(
+        typeContext, node.fileOffset, calleeType, node.arguments);
     Expression replacement = new StaticInvocation(node.target, node.arguments);
     if (!inferrer.isTopLevel &&
         !hadExplicitTypeArguments &&
@@ -531,12 +528,9 @@
       FactoryConstructorInvocationJudgment node, DartType typeContext) {
     bool hadExplicitTypeArguments =
         getExplicitTypeArguments(node.arguments) != null;
-    DartType inferredType = inferrer.inferInvocation(
-        typeContext,
-        node.fileOffset,
-        node.target.function.thisFunctionType,
-        computeConstructorReturnType(node.target),
-        node.arguments,
+    DartType inferredType = inferrer.inferInvocation(typeContext,
+        node.fileOffset, node.target.function.thisFunctionType, node.arguments,
+        returnType: computeConstructorReturnType(node.target),
         isConst: node.isConst);
     node.hasBeenInferred = true;
     if (!inferrer.isTopLevel) {
@@ -795,8 +789,8 @@
         node.fileOffset,
         substitution.substituteType(
             node.target.function.thisFunctionType.withoutTypeParameters),
-        inferrer.thisType,
         node.argumentsJudgment,
+        returnType: inferrer.thisType,
         skipTypeArgumentInference: true);
   }
 
@@ -1386,9 +1380,13 @@
           mapEntryClass, <DartType>[actualKeyType, actualValueType]);
 
       bool isMap = inferrer.typeSchemaEnvironment.isSubtypeOf(
-          spreadType, inferrer.coreTypes.mapRawType(inferrer.library.nullable));
-      bool isIterable = inferrer.typeSchemaEnvironment.isSubtypeOf(spreadType,
-          inferrer.coreTypes.iterableRawType(inferrer.library.nullable));
+          spreadType,
+          inferrer.coreTypes.mapRawType(inferrer.library.nullable),
+          SubtypeCheckMode.ignoringNullabilities);
+      bool isIterable = inferrer.typeSchemaEnvironment.isSubtypeOf(
+          spreadType,
+          inferrer.coreTypes.iterableRawType(inferrer.library.nullable),
+          SubtypeCheckMode.ignoringNullabilities);
       if (isMap && !isIterable) {
         mapSpreadOffset = entry.fileOffset;
       }
@@ -4162,12 +4160,9 @@
       typeArguments[i] = new TypeParameterType(classTypeParameters[i]);
     }
     ArgumentsImpl.setNonInferrableArgumentTypes(node.arguments, typeArguments);
-    inferrer.inferInvocation(
-        null,
-        node.fileOffset,
-        node.target.function.thisFunctionType,
-        node.target.enclosingClass.thisType,
-        node.arguments,
+    inferrer.inferInvocation(null, node.fileOffset,
+        node.target.function.thisFunctionType, node.arguments,
+        returnType: node.target.enclosingClass.thisType,
         skipTypeArgumentInference: true);
     ArgumentsImpl.removeNonInferrableArgumentTypes(node.arguments);
   }
@@ -4313,8 +4308,8 @@
         : new FunctionType([], const DynamicType());
     bool hadExplicitTypeArguments =
         getExplicitTypeArguments(node.arguments) != null;
-    DartType inferredType = inferrer.inferInvocation(typeContext,
-        node.fileOffset, calleeType, calleeType.returnType, node.arguments);
+    DartType inferredType = inferrer.inferInvocation(
+        typeContext, node.fileOffset, calleeType, node.arguments);
     if (!inferrer.isTopLevel &&
         !hadExplicitTypeArguments &&
         node.target != null) {
@@ -4356,8 +4351,8 @@
         node.fileOffset,
         substitution.substituteType(
             node.target.function.thisFunctionType.withoutTypeParameters),
-        inferrer.thisType,
         node.arguments,
+        returnType: inferrer.thisType,
         skipTypeArgumentInference: true);
   }
 
@@ -4620,8 +4615,8 @@
         inferrer.typeSchemaEnvironment.futureType(const DynamicType());
     if (node.arguments != null) {
       FunctionType calleeType = new FunctionType([], inferredType);
-      inferrer.inferInvocation(typeContext, node.fileOffset, calleeType,
-          calleeType.returnType, node.arguments);
+      inferrer.inferInvocation(
+          typeContext, node.fileOffset, calleeType, node.arguments);
     }
     return new ExpressionInferenceResult(inferredType);
   }
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 627fbc5..e1dbaf4 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
@@ -24,6 +24,8 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
+import 'package:kernel/type_environment.dart';
+
 import 'package:kernel/clone.dart';
 
 import '../../base/instrumentation.dart'
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
index 6e519f9..0e7d4d4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
@@ -46,7 +46,8 @@
 
 import 'package:kernel/core_types.dart' show CoreTypes;
 
-import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/type_environment.dart'
+    show SubtypeCheckMode, TypeEnvironment;
 
 import 'package:kernel/visitor.dart' show Transformer;
 
@@ -248,7 +249,8 @@
     VariableDeclaration elt;
     Statement loopBody;
     if (element.elementType == null ||
-        !typeEnvironment.isSubtypeOf(element.elementType, elementType)) {
+        !typeEnvironment.isSubtypeOf(element.elementType, elementType,
+            SubtypeCheckMode.ignoringNullabilities)) {
       elt = new VariableDeclaration(null,
           type: const DynamicType(), isFinal: true);
       VariableDeclaration castedVar = new VariableDeclaration.forValue(
@@ -439,7 +441,8 @@
     VariableDeclaration elt;
     Statement loopBody;
     if (entry.entryType == null ||
-        !typeEnvironment.isSubtypeOf(entry.entryType, entryType)) {
+        !typeEnvironment.isSubtypeOf(entry.entryType, entryType,
+            SubtypeCheckMode.ignoringNullabilities)) {
       elt = new VariableDeclaration(null,
           type: new InterfaceType(mapEntryClass,
               <DartType>[const DynamicType(), const DynamicType()]),
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index 544ff1d..bcceaad 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -120,6 +120,29 @@
   return Variance.unrelated;
 }
 
+/// Combines syntactic nullabilities on types for performing type substitution.
+///
+/// The syntactic substitution should preserve a `?` if it was either on the
+/// type parameter occurrence or on the type argument replacing it.
+NullabilityBuilder combineNullabilityBuildersForSubstitution(
+    NullabilityBuilder a, NullabilityBuilder b) {
+  assert(
+      (identical(a, const NullabilityBuilder.nullable()) ||
+              identical(a, const NullabilityBuilder.omitted())) &&
+          (identical(b, const NullabilityBuilder.nullable()) ||
+              identical(b, const NullabilityBuilder.omitted())),
+      "Both arguments to combineNullabilityBuildersForSubstitution "
+      "should be identical to either 'const NullabilityBuilder.nullable()' or "
+      "'const NullabilityBuilder.omitted()'.");
+
+  if (identical(a, const NullabilityBuilder.nullable()) ||
+      identical(b, const NullabilityBuilder.nullable())) {
+    return const NullabilityBuilder.nullable();
+  }
+
+  return const NullabilityBuilder.omitted();
+}
+
 TypeBuilder substituteRange(
     TypeBuilder type,
     Map<TypeVariableBuilder, TypeBuilder> upperSubstitution,
@@ -130,9 +153,21 @@
   if (type is NamedTypeBuilder) {
     if (type.declaration is TypeVariableBuilder) {
       if (variance == Variance.contravariant) {
-        return lowerSubstitution[type.declaration] ?? type;
+        TypeBuilder replacement = lowerSubstitution[type.declaration];
+        if (replacement != null) {
+          return replacement.withNullabilityBuilder(
+              combineNullabilityBuildersForSubstitution(
+                  replacement.nullabilityBuilder, type.nullabilityBuilder));
+        }
+        return type;
       }
-      return upperSubstitution[type.declaration] ?? type;
+      TypeBuilder replacement = upperSubstitution[type.declaration];
+      if (replacement != null) {
+        return replacement.withNullabilityBuilder(
+            combineNullabilityBuildersForSubstitution(
+                replacement.nullabilityBuilder, type.nullabilityBuilder));
+      }
+      return type;
     }
     if (type.arguments == null || type.arguments.length == 0) {
       return type;
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
index 45d0275..0bb51ac 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -178,6 +178,7 @@
           result.add(" extends ");
           param.bound.accept(this);
         }
+        first = false;
       }
       result.add(">");
     }
diff --git a/pkg/front_end/lib/src/fasta/kernel/types.dart b/pkg/front_end/lib/src/fasta/kernel/types.dart
index a70d416..bf19015 100644
--- a/pkg/front_end/lib/src/fasta/kernel/types.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/types.dart
@@ -22,6 +22,8 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
+import 'package:kernel/type_environment.dart';
+
 import 'kernel_builder.dart' show ClassHierarchyBuilder;
 
 class Types {
@@ -30,7 +32,7 @@
   Types(this.hierarchy);
 
   /// Returns true if [s] is a subtype of [t].
-  bool isSubtypeOfKernel(DartType s, DartType t) {
+  bool isSubtypeOfKernel(DartType s, DartType t, SubtypeCheckMode mode) {
     if (s is InvalidType) {
       // InvalidType is a bottom type.
       return true;
@@ -231,13 +233,15 @@
       throw "Numbers of type arguments don't match $s $t.";
     }
     for (int i = 0; i < s.length; i++) {
-      if (!isSubtypeOfKernel(s[i], t[i])) return false;
+      if (!isSubtypeOfKernel(
+          s[i], t[i], SubtypeCheckMode.ignoringNullabilities)) return false;
     }
     return true;
   }
 
   bool isSameTypeKernel(DartType s, DartType t) {
-    return isSubtypeOfKernel(s, t) && isSubtypeOfKernel(t, s);
+    return isSubtypeOfKernel(s, t, SubtypeCheckMode.ignoringNullabilities) &&
+        isSubtypeOfKernel(t, s, SubtypeCheckMode.ignoringNullabilities);
   }
 }
 
@@ -301,7 +305,8 @@
   @override
   bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
       InterfaceType t, Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s.parameter.bound, t);
+    return types.isSubtypeOfKernel(
+        s.parameter.bound, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -312,11 +317,14 @@
       Nullability tNullability,
       Types types) {
     List<DartType> arguments = futureOr.typeArguments;
-    if (!types.isSubtypeOfKernel(arguments.single, t)) {
+    if (!types.isSubtypeOfKernel(
+        arguments.single, t, SubtypeCheckMode.ignoringNullabilities)) {
       return false; // Rule 7.1
     }
     if (!types.isSubtypeOfKernel(
-        new InterfaceType(types.hierarchy.futureClass, arguments), t)) {
+        new InterfaceType(types.hierarchy.futureClass, arguments),
+        t,
+        SubtypeCheckMode.ignoringNullabilities)) {
       return false; // Rule 7.2
     }
     return true;
@@ -329,7 +337,8 @@
       InterfaceType t,
       Nullability tNullability,
       Types types) {
-    return types.isSubtypeOfKernel(intersection.promotedBound, t); // Rule 12.
+    return types.isSubtypeOfKernel(intersection.promotedBound, t,
+        SubtypeCheckMode.ignoringNullabilities); // Rule 12.
   }
 
   @override
@@ -348,7 +357,8 @@
   bool isTypedefRelated(TypedefType s, Nullability sNullability,
       InterfaceType t, Nullability tNullability, Types types) {
     // Rule 5.
-    return types.isSubtypeOfKernel(s.unalias, t);
+    return types.isSubtypeOfKernel(
+        s.unalias, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -397,7 +407,10 @@
       }
       s = substitution.substituteType(s.withoutTypeParameters);
     }
-    if (!types.isSubtypeOfKernel(s.returnType, t.returnType)) return false;
+    if (!types.isSubtypeOfKernel(
+        s.returnType, t.returnType, SubtypeCheckMode.ignoringNullabilities)) {
+      return false;
+    }
     List<DartType> sPositional = s.positionalParameters;
     List<DartType> tPositional = t.positionalParameters;
     if (s.requiredParameterCount > t.requiredParameterCount) {
@@ -409,7 +422,8 @@
       return false;
     }
     for (int i = 0; i < tPositional.length; i++) {
-      if (!types.isSubtypeOfKernel(tPositional[i], sPositional[i])) {
+      if (!types.isSubtypeOfKernel(tPositional[i], sPositional[i],
+          SubtypeCheckMode.ignoringNullabilities)) {
         // Rule 15, Tj <: Sj.
         return false;
       }
@@ -431,8 +445,8 @@
           if (sNamed[sCount].name == name) break;
         }
         if (sCount == sNamed.length) return false;
-        if (!types.isSubtypeOfKernel(
-            tNamed[tCount].type, sNamed[sCount].type)) {
+        if (!types.isSubtypeOfKernel(tNamed[tCount].type, sNamed[sCount].type,
+            SubtypeCheckMode.ignoringNullabilities)) {
           return false;
         }
       }
@@ -470,21 +484,24 @@
       Nullability tNullability,
       Types types) {
     // Rule 12.
-    return types.isSubtypeOfKernel(intersection.promotedBound, t);
+    return types.isSubtypeOfKernel(
+        intersection.promotedBound, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
       FunctionType t, Nullability tNullability, Types types) {
     // Rule 13.
-    return types.isSubtypeOfKernel(s.parameter.bound, t);
+    return types.isSubtypeOfKernel(
+        s.parameter.bound, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypedefRelated(TypedefType s, Nullability sNullability, FunctionType t,
       Nullability tNullability, Types types) {
     // Rule 5.
-    return types.isSubtypeOfKernel(s.unalias, t);
+    return types.isSubtypeOfKernel(
+        s.unalias, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -502,7 +519,8 @@
       TypeParameterType t, Nullability tNullability, Types types) {
     return s.parameter == t.parameter ||
         // Rule 13.
-        types.isSubtypeOfKernel(s.bound, t);
+        types.isSubtypeOfKernel(
+            s.bound, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -546,7 +564,8 @@
   @override
   bool isTypedefRelated(TypedefType s, Nullability sNullability,
       TypeParameterType t, Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s.unalias, t);
+    return types.isSubtypeOfKernel(
+        s.unalias, t, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -562,19 +581,22 @@
   @override
   bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
       TypedefType t, Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s, t.unalias);
+    return types.isSubtypeOfKernel(
+        s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isDynamicRelated(DynamicType s, Nullability sNullability, TypedefType t,
       Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s, t.unalias);
+    return types.isSubtypeOfKernel(
+        s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isFunctionRelated(FunctionType s, Nullability sNullability,
       TypedefType t, Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s, t.unalias);
+    return types.isSubtypeOfKernel(
+        s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -584,7 +606,8 @@
       TypedefType t,
       Nullability tNullability,
       Types types) {
-    return types.isSubtypeOfKernel(futureOr, t.unalias);
+    return types.isSubtypeOfKernel(
+        futureOr, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -594,25 +617,29 @@
       TypedefType t,
       Nullability tNullability,
       Types types) {
-    return types.isSubtypeOfKernel(intersection, t.unalias);
+    return types.isSubtypeOfKernel(
+        intersection, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
       TypedefType t, Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s, t.unalias);
+    return types.isSubtypeOfKernel(
+        s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypedefRelated(TypedefType s, Nullability sNullability, TypedefType t,
       Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s.unalias, t.unalias);
+    return types.isSubtypeOfKernel(
+        s.unalias, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isVoidRelated(VoidType s, Nullability sNullability, TypedefType t,
       Nullability tNullability, Types types) {
-    return types.isSubtypeOfKernel(s, t.unalias);
+    return types.isSubtypeOfKernel(
+        s, t.unalias, SubtypeCheckMode.ignoringNullabilities);
   }
 }
 
@@ -623,12 +650,15 @@
   bool isInterfaceRelated(InterfaceType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     List<DartType> arguments = futureOr.typeArguments;
-    if (types.isSubtypeOfKernel(s, arguments.single)) {
+    if (types.isSubtypeOfKernel(
+        s, arguments.single, SubtypeCheckMode.ignoringNullabilities)) {
       return true; // Rule 11.
     }
     // Rule 10.
     return types.isSubtypeOfKernel(
-        s, new InterfaceType(types.hierarchy.futureClass, arguments));
+        s,
+        new InterfaceType(types.hierarchy.futureClass, arguments),
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -639,48 +669,55 @@
       Nullability tFutureOrNullability,
       Types types) {
     // This follows from combining rules 7, 10, and 11.
-    return types.isSubtypeOfKernel(
-        sFutureOr.typeArguments.single, tFutureOr.typeArguments.single);
+    return types.isSubtypeOfKernel(sFutureOr.typeArguments.single,
+        tFutureOr.typeArguments.single, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isDynamicRelated(DynamicType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     // Rule 11.
-    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
+    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single,
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isVoidRelated(VoidType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     // Rule 11.
-    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
+    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single,
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypeParameterRelated(TypeParameterType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     List<DartType> arguments = futureOr.typeArguments;
-    if (types.isSubtypeOfKernel(s, arguments.single)) {
+    if (types.isSubtypeOfKernel(
+        s, arguments.single, SubtypeCheckMode.ignoringNullabilities)) {
       // Rule 11.
       return true;
     }
 
-    if (types.isSubtypeOfKernel(s.parameter.bound, futureOr)) {
+    if (types.isSubtypeOfKernel(
+        s.parameter.bound, futureOr, SubtypeCheckMode.ignoringNullabilities)) {
       // Rule 13.
       return true;
     }
 
     // Rule 10.
     return types.isSubtypeOfKernel(
-        s, new InterfaceType(types.hierarchy.futureClass, arguments));
+        s,
+        new InterfaceType(types.hierarchy.futureClass, arguments),
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isFunctionRelated(FunctionType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
     // Rule 11.
-    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single);
+    return types.isSubtypeOfKernel(s, futureOr.typeArguments.single,
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -696,13 +733,15 @@
       return true;
     }
     // Rule 12.
-    return types.isSubtypeOfKernel(intersection.promotedBound, futureOr);
+    return types.isSubtypeOfKernel(intersection.promotedBound, futureOr,
+        SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
   bool isTypedefRelated(TypedefType s, Nullability sNullability,
       InterfaceType futureOr, Nullability futureOrNullability, Types types) {
-    return types.isSubtypeOfKernel(s.unalias, futureOr);
+    return types.isSubtypeOfKernel(
+        s.unalias, futureOr, SubtypeCheckMode.ignoringNullabilities);
   }
 }
 
@@ -723,7 +762,8 @@
             tIntersection,
             tIntersectionNullability,
             types) &&
-        types.isSubtypeOfKernel(sIntersection, tIntersection.promotedBound);
+        types.isSubtypeOfKernel(sIntersection, tIntersection.promotedBound,
+            SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -736,7 +776,8 @@
     // Rule 9.
     return const IsTypeParameterSubtypeOf().isTypeParameterRelated(
             s, sNullability, intersection, intersectionNullability, types) &&
-        types.isSubtypeOfKernel(s, intersection.promotedBound);
+        types.isSubtypeOfKernel(s, intersection.promotedBound,
+            SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
@@ -787,7 +828,8 @@
       Nullability intersectionNullability,
       Types types) {
     // Rule 5.
-    return types.isSubtypeOfKernel(s.unalias, intersection);
+    return types.isSubtypeOfKernel(
+        s.unalias, intersection, SubtypeCheckMode.ignoringNullabilities);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index f2753bd..9e548fb 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -3444,7 +3444,7 @@
               beforeInitializers?.next, token);
           break;
         case DeclarationKind.Extension:
-          if (optional(';', bodyStart)) {
+          if (optional(';', bodyStart) && externalToken == null) {
             reportRecoverableError(isOperator ? name.next : name,
                 fasta.messageExtensionDeclaresAbstractMember);
           }
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
index fd7df17..09ac319 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -4,6 +4,7 @@
 
 import 'dart:core' hide MapEntry;
 import 'package:kernel/ast.dart';
+import '../../base/common.dart';
 import '../builder/declaration.dart';
 import '../builder/extension_builder.dart';
 import '../builder/library_builder.dart';
@@ -12,22 +13,26 @@
 import '../builder/type_builder.dart';
 import '../builder/type_variable_builder.dart';
 import '../scope.dart';
-import 'source_library_builder.dart';
 import '../kernel/kernel_builder.dart';
-
 import '../problems.dart';
-
 import '../fasta_codes.dart'
     show
+        messagePatchDeclarationMismatch,
+        messagePatchDeclarationOrigin,
         noLength,
         templateConflictsWithMember,
         templateConflictsWithMemberWarning,
         templateConflictsWithSetter,
-        templateConflictsWithSetterWarning;
+        templateConflictsWithSetterWarning,
+        templateExtensionMemberConflictsWithObjectMember;
+import 'source_library_builder.dart';
 
 class SourceExtensionBuilder extends ExtensionBuilder {
   final Extension _extension;
 
+  SourceExtensionBuilder _origin;
+  SourceExtensionBuilder patchForTesting;
+
   SourceExtensionBuilder(
       List<MetadataBuilder> metadata,
       int modifiers,
@@ -48,7 +53,10 @@
         super(metadata, modifiers, name, parent, nameOffset, scope,
             typeParameters, onType);
 
-  Extension get extension => _extension;
+  @override
+  SourceExtensionBuilder get origin => _origin ?? this;
+
+  Extension get extension => isPatch ? origin._extension : _extension;
 
   /// Builds the [Extension] for this extension build and inserts the members
   /// into the [Library] of [libraryBuilder].
@@ -61,8 +69,20 @@
   Extension build(
       SourceLibraryBuilder libraryBuilder, LibraryBuilder coreLibrary,
       {bool addMembersToLibrary}) {
+    ClassBuilder objectClassBuilder =
+        coreLibrary.lookupLocalMember('Object', required: true);
     void buildBuilders(String name, Builder declaration) {
       do {
+        Builder objectGetter = objectClassBuilder.lookupLocalMember(name);
+        Builder objectSetter =
+            objectClassBuilder.lookupLocalMember(name, setter: true);
+        if (objectGetter != null || objectSetter != null) {
+          addProblem(
+              templateExtensionMemberConflictsWithObjectMember
+                  .withArguments(name),
+              declaration.charOffset,
+              name.length);
+        }
         if (declaration.parent != this) {
           if (fileUri != declaration.parent.fileUri) {
             unexpected("$fileUri", "${declaration.parent.fileUri}", charOffset,
@@ -75,7 +95,7 @@
           Field field = declaration.build(libraryBuilder);
           if (addMembersToLibrary && declaration.next == null) {
             libraryBuilder.library.addMember(field);
-            _extension.members.add(new ExtensionMemberDescriptor(
+            extension.members.add(new ExtensionMemberDescriptor(
                 name: new Name(declaration.name, libraryBuilder.library),
                 member: field.reference,
                 isStatic: declaration.isStatic,
@@ -83,7 +103,9 @@
           }
         } else if (declaration is ProcedureBuilder) {
           Member function = declaration.build(libraryBuilder);
-          if (addMembersToLibrary && declaration.next == null) {
+          if (addMembersToLibrary &&
+              !declaration.isPatch &&
+              declaration.next == null) {
             libraryBuilder.library.addMember(function);
             ExtensionMemberKind kind;
             switch (declaration.kind) {
@@ -103,11 +125,10 @@
                 unsupported("Extension method kind: ${declaration.kind}",
                     declaration.charOffset, declaration.fileUri);
             }
-            _extension.members.add(new ExtensionMemberDescriptor(
+            extension.members.add(new ExtensionMemberDescriptor(
                 name: new Name(declaration.name, libraryBuilder.library),
                 member: function.reference,
                 isStatic: declaration.isStatic,
-                isExternal: declaration.isExternal,
                 kind: kind));
             Procedure tearOff = declaration.extensionTearOff;
             if (tearOff != null) {
@@ -116,7 +137,6 @@
                   name: new Name(declaration.name, libraryBuilder.library),
                   member: tearOff.reference,
                   isStatic: false,
-                  isExternal: false,
                   kind: ExtensionMemberKind.TearOff));
             }
           }
@@ -157,4 +177,46 @@
 
     return _extension;
   }
+
+  @override
+  void applyPatch(Builder patch) {
+    if (patch is SourceExtensionBuilder) {
+      patch._origin = this;
+      if (retainDataForTesting) {
+        patchForTesting = patch;
+      }
+      scope.local.forEach((String name, Builder member) {
+        Builder memberPatch = patch.scope.local[name];
+        if (memberPatch != null) {
+          member.applyPatch(memberPatch);
+        }
+      });
+      scope.setters.forEach((String name, Builder member) {
+        Builder memberPatch = patch.scope.setters[name];
+        if (memberPatch != null) {
+          member.applyPatch(memberPatch);
+        }
+      });
+
+      // TODO(johnniwinther): Check that type parameters and on-type match
+      // with origin declaration.
+    } else {
+      library.addProblem(messagePatchDeclarationMismatch, patch.charOffset,
+          noLength, patch.fileUri, context: [
+        messagePatchDeclarationOrigin.withLocation(
+            fileUri, charOffset, noLength)
+      ]);
+    }
+  }
+
+  @override
+  int finishPatch() {
+    if (!isPatch) return 0;
+
+    int count = 0;
+    scope.forEach((String name, Builder declaration) {
+      count += declaration.finishPatch();
+    });
+    return count;
+  }
 }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
index f2243b2..83ce151 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
@@ -20,6 +20,8 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
+import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+
 import 'type_schema.dart' show UnknownType;
 
 abstract class StandardBounds {
@@ -30,7 +32,7 @@
   InterfaceType get objectLegacyRawType;
   InterfaceType get functionLegacyRawType;
 
-  bool isSubtypeOf(DartType subtype, DartType supertype);
+  bool isSubtypeOf(DartType subtype, DartType supertype, SubtypeCheckMode mode);
 
   InterfaceType getLegacyLeastUpperBound(
       InterfaceType type1, InterfaceType type2);
@@ -94,11 +96,11 @@
 
     // Otherwise, the lower bounds  of two types is one of them it if it is a
     // subtype of the other.
-    if (isSubtypeOf(type1, type2)) {
+    if (isSubtypeOf(type1, type2, SubtypeCheckMode.ignoringNullabilities)) {
       return type1;
     }
 
-    if (isSubtypeOf(type2, type1)) {
+    if (isSubtypeOf(type2, type1, SubtypeCheckMode.ignoringNullabilities)) {
       return type2;
     }
 
@@ -408,10 +410,10 @@
     // 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)) {
+    if (isSubtypeOf(type1, type2, SubtypeCheckMode.ignoringNullabilities)) {
       return type2;
     }
-    if (isSubtypeOf(type2, type1)) {
+    if (isSubtypeOf(type2, type1, SubtypeCheckMode.ignoringNullabilities)) {
       return type1;
     }
     if (type1 is InterfaceType &&
@@ -463,10 +465,10 @@
     // type variable first.  Alternatively, you could probably choose to treat
     // it as just an instance of the interface type upper bound problem, with
     // the "inheritance" chain extended by the bounds placed on the variables.
-    if (isSubtypeOf(type1, type2)) {
+    if (isSubtypeOf(type1, type2, SubtypeCheckMode.ignoringNullabilities)) {
       return type2;
     }
-    if (isSubtypeOf(type2, type1)) {
+    if (isSubtypeOf(type2, type1, SubtypeCheckMode.ignoringNullabilities)) {
       return type1;
     }
     if (type1 is TypeParameterType) {
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 faf4afd..e51fb8d 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
@@ -12,8 +12,9 @@
 
 import 'package:kernel/core_types.dart' show CoreTypes;
 
-import 'package:kernel/type_algebra.dart'
-    show FreshTypeParameters, getFreshTypeParameters, Substitution;
+import 'package:kernel/type_algebra.dart';
+
+import 'package:kernel/type_environment.dart';
 
 import 'package:kernel/src/bounds_checks.dart' show calculateBounds;
 
@@ -349,8 +350,8 @@
     assert(_needToInferReturnType);
     DartType inferredType =
         inferrer.inferReturnType(_inferredUnwrappedReturnOrYieldType);
-    if (!inferrer.typeSchemaEnvironment
-        .isSubtypeOf(inferredType, returnOrYieldContext)) {
+    if (!inferrer.typeSchemaEnvironment.isSubtypeOf(inferredType,
+        returnOrYieldContext, SubtypeCheckMode.ignoringNullabilities)) {
       // If the inferred return type isn't a subtype of the context, we use the
       // context.
       inferredType = greatestClosure(inferrer.coreTypes, returnOrYieldContext);
@@ -525,8 +526,10 @@
   }
 
   bool isAssignable(DartType expectedType, DartType actualType) {
-    return typeSchemaEnvironment.isSubtypeOf(expectedType, actualType) ||
-        typeSchemaEnvironment.isSubtypeOf(actualType, expectedType);
+    return typeSchemaEnvironment.isSubtypeOf(
+            expectedType, actualType, SubtypeCheckMode.ignoringNullabilities) ||
+        typeSchemaEnvironment.isSubtypeOf(
+            actualType, expectedType, SubtypeCheckMode.ignoringNullabilities);
   }
 
   /// Checks whether [actualType] can be assigned to the greatest closure of
@@ -602,12 +605,14 @@
     }
 
     if (expectedType == null ||
-        typeSchemaEnvironment.isSubtypeOf(actualType, expectedType)) {
+        typeSchemaEnvironment.isSubtypeOf(
+            actualType, expectedType, SubtypeCheckMode.ignoringNullabilities)) {
       // Types are compatible.
       return null;
     }
 
-    if (!typeSchemaEnvironment.isSubtypeOf(expectedType, actualType)) {
+    if (!typeSchemaEnvironment.isSubtypeOf(
+        expectedType, actualType, SubtypeCheckMode.ignoringNullabilities)) {
       // Error: not assignable.  Perform error recovery.
       TreeNode parent = expression.parent;
       Expression errorNode = new AsExpression(
@@ -790,7 +795,8 @@
               DartType typeArgument = inferredTypeArguments[index];
               DartType bound =
                   inferredSubstitution.substituteType(typeParameter.bound);
-              if (!typeSchemaEnvironment.isSubtypeOf(typeArgument, bound)) {
+              if (!typeSchemaEnvironment.isSubtypeOf(typeArgument, bound,
+                  SubtypeCheckMode.ignoringNullabilities)) {
                 return;
               }
             }
@@ -805,7 +811,8 @@
                 .substituteType(extensionBuilder.extension.onType);
           }
 
-          if (typeSchemaEnvironment.isSubtypeOf(receiverType, onType)) {
+          if (typeSchemaEnvironment.isSubtypeOf(
+              receiverType, onType, SubtypeCheckMode.ignoringNullabilities)) {
             ExtensionAccessCandidate candidate = new ExtensionAccessCandidate(
                 onType,
                 onTypeInstantiateToBounds,
@@ -1639,26 +1646,33 @@
   }
 
   DartType inferInvocation(DartType typeContext, int offset,
-      FunctionType calleeType, DartType returnType, Arguments arguments,
+      FunctionType calleeType, Arguments arguments,
       {bool isOverloadedArithmeticOperator: false,
+      DartType returnType,
       DartType receiverType,
       bool skipTypeArgumentInference: false,
       bool isConst: false,
       bool isImplicitExtensionMember: false}) {
+    assert(
+        returnType == null || !containsFreeFunctionTypeVariables(returnType),
+        "Return type $returnType contains free variables."
+        "Provided function type: $calleeType.");
     int extensionTypeParameterCount = getExtensionTypeParameterCount(arguments);
     if (extensionTypeParameterCount != 0) {
+      assert(returnType == null,
+          "Unexpected explicit return type for extension method invocation.");
       return _inferGenericExtensionMethodInvocation(extensionTypeParameterCount,
-          typeContext, offset, calleeType, returnType, arguments,
+          typeContext, offset, calleeType, arguments,
           isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
           receiverType: receiverType,
           skipTypeArgumentInference: skipTypeArgumentInference,
           isConst: isConst,
           isImplicitExtensionMember: isImplicitExtensionMember);
     }
-    return _inferInvocation(
-        typeContext, offset, calleeType, returnType, arguments,
+    return _inferInvocation(typeContext, offset, calleeType, arguments,
         isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
         receiverType: receiverType,
+        returnType: returnType,
         skipTypeArgumentInference: skipTypeArgumentInference,
         isConst: isConst,
         isImplicitExtensionMember: isImplicitExtensionMember);
@@ -1669,7 +1683,6 @@
       DartType typeContext,
       int offset,
       FunctionType calleeType,
-      DartType returnType,
       Arguments arguments,
       {bool isOverloadedArithmeticOperator: false,
       DartType receiverType,
@@ -1685,8 +1698,8 @@
     Arguments extensionArguments = helper.forest.createArguments(
         arguments.fileOffset, [arguments.positional.first],
         types: getExplicitExtensionTypeArguments(arguments));
-    _inferInvocation(const UnknownType(), offset, extensionFunctionType,
-        extensionFunctionType.returnType, extensionArguments,
+    _inferInvocation(
+        const UnknownType(), offset, extensionFunctionType, extensionArguments,
         skipTypeArgumentInference: skipTypeArgumentInference,
         receiverType: receiverType,
         isImplicitExtensionMember: isImplicitExtensionMember);
@@ -1705,13 +1718,11 @@
         typeParameters: targetTypeParameters);
     targetFunctionType =
         extensionSubstitution.substituteType(targetFunctionType);
-    DartType targetReturnType =
-        extensionSubstitution.substituteType(returnType);
     Arguments targetArguments = helper.forest.createArguments(
         arguments.fileOffset, arguments.positional.skip(1).toList(),
         named: arguments.named, types: getExplicitTypeArguments(arguments));
-    DartType inferredType = _inferInvocation(typeContext, offset,
-        targetFunctionType, targetReturnType, targetArguments,
+    DartType inferredType = _inferInvocation(
+        typeContext, offset, targetFunctionType, targetArguments,
         isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
         skipTypeArgumentInference: skipTypeArgumentInference,
         isConst: isConst);
@@ -1731,13 +1742,18 @@
   /// Performs the type inference steps that are shared by all kinds of
   /// invocations (constructors, instance methods, and static methods).
   DartType _inferInvocation(DartType typeContext, int offset,
-      FunctionType calleeType, DartType returnType, Arguments arguments,
+      FunctionType calleeType, Arguments arguments,
       {bool isOverloadedArithmeticOperator: false,
       bool isBinaryOperator: false,
       DartType receiverType,
+      DartType returnType,
       bool skipTypeArgumentInference: false,
       bool isConst: false,
       bool isImplicitExtensionMember: false}) {
+    assert(
+        returnType == null || !containsFreeFunctionTypeVariables(returnType),
+        "Return type $returnType contains free variables."
+        "Provided function type: $calleeType.");
     lastInferredSubstitution = null;
     lastCalleeType = null;
     List<TypeParameter> calleeTypeParameters = calleeType.typeParameters;
@@ -1753,7 +1769,9 @@
       // in which me must do this, to avoid a performance regression?
       FreshTypeParameters fresh = getFreshTypeParameters(calleeTypeParameters);
       calleeType = fresh.applyToFunctionType(calleeType);
-      returnType = fresh.substitute(returnType);
+      if (returnType != null) {
+        returnType = fresh.substitute(returnType);
+      }
       calleeTypeParameters = fresh.freshTypeParameters;
     }
     List<DartType> explicitTypeArguments = getExplicitTypeArguments(arguments);
@@ -1776,8 +1794,13 @@
       }
       inferredTypes = new List<DartType>.filled(
           calleeTypeParameters.length, const UnknownType());
-      typeSchemaEnvironment.inferGenericFunctionOrType(returnType,
-          calleeTypeParameters, null, null, typeContext, inferredTypes);
+      typeSchemaEnvironment.inferGenericFunctionOrType(
+          returnType ?? calleeType.returnType,
+          calleeTypeParameters,
+          null,
+          null,
+          typeContext,
+          inferredTypes);
       substitution =
           Substitution.fromPairs(calleeTypeParameters, inferredTypes);
     } else if (explicitTypeArguments != null &&
@@ -1869,7 +1892,7 @@
 
     if (inferenceNeeded) {
       typeSchemaEnvironment.inferGenericFunctionOrType(
-          returnType,
+          returnType ?? calleeType.returnType,
           calleeTypeParameters,
           formalTypes,
           actualTypes,
@@ -1912,9 +1935,21 @@
     DartType inferredType;
     lastInferredSubstitution = substitution;
     lastCalleeType = calleeType;
-    inferredType = substitution == null
-        ? returnType
-        : substitution.substituteType(returnType);
+    if (returnType != null) {
+      inferredType = substitution == null
+          ? returnType
+          : substitution.substituteType(returnType);
+    } else {
+      if (substitution != null) {
+        calleeType =
+            substitution.substituteType(calleeType.withoutTypeParameters);
+      }
+      inferredType = calleeType.returnType;
+    }
+    assert(
+        !containsFreeFunctionTypeVariables(inferredType),
+        "Inferred return type $inferredType contains free variables."
+        "Inferred function type: $calleeType.");
     return inferredType;
   }
 
@@ -2142,8 +2177,8 @@
           target, node, node.receiver, arguments);
       arguments = replacement.arguments;
     }
-    DartType inferredType = inferInvocation(typeContext, node.fileOffset,
-        functionType, functionType.returnType, arguments,
+    DartType inferredType = inferInvocation(
+        typeContext, node.fileOffset, functionType, arguments,
         isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
         receiverType: receiverType,
         isImplicitExtensionMember: target.isExtensionMember);
@@ -2252,8 +2287,8 @@
       parent?.replaceChild(expression, error);
       return const ExpressionInferenceResult(const DynamicType());
     }
-    DartType inferredType = inferInvocation(typeContext, fileOffset,
-        functionType, functionType.returnType, arguments,
+    DartType inferredType = inferInvocation(
+        typeContext, fileOffset, functionType, arguments,
         isOverloadedArithmeticOperator: isOverloadedArithmeticOperator,
         receiverType: receiverType,
         isImplicitExtensionMember: target.isExtensionMember);
@@ -2614,7 +2649,8 @@
     }
     if (expectedType is FunctionType) return true;
     if (expectedType == typeSchemaEnvironment.functionLegacyRawType) {
-      if (!typeSchemaEnvironment.isSubtypeOf(actualType, expectedType)) {
+      if (!typeSchemaEnvironment.isSubtypeOf(
+          actualType, expectedType, SubtypeCheckMode.ignoringNullabilities)) {
         return true;
       }
     }
@@ -2915,10 +2951,10 @@
       ExtensionAccessCandidate other) {
     if (this.isPlatform == other.isPlatform) {
       // Both are platform or not platform.
-      bool thisIsSubtype =
-          typeSchemaEnvironment.isSubtypeOf(this.onType, other.onType);
-      bool thisIsSupertype =
-          typeSchemaEnvironment.isSubtypeOf(other.onType, this.onType);
+      bool thisIsSubtype = typeSchemaEnvironment.isSubtypeOf(
+          this.onType, other.onType, SubtypeCheckMode.ignoringNullabilities);
+      bool thisIsSupertype = typeSchemaEnvironment.isSubtypeOf(
+          other.onType, this.onType, SubtypeCheckMode.ignoringNullabilities);
       if (thisIsSubtype && !thisIsSupertype) {
         // This is subtype of other and not vice-versa.
         return true;
@@ -2927,9 +2963,13 @@
         return false;
       } else if (thisIsSubtype || thisIsSupertype) {
         thisIsSubtype = typeSchemaEnvironment.isSubtypeOf(
-            this.onTypeInstantiateToBounds, other.onTypeInstantiateToBounds);
+            this.onTypeInstantiateToBounds,
+            other.onTypeInstantiateToBounds,
+            SubtypeCheckMode.ignoringNullabilities);
         thisIsSupertype = typeSchemaEnvironment.isSubtypeOf(
-            other.onTypeInstantiateToBounds, this.onTypeInstantiateToBounds);
+            other.onTypeInstantiateToBounds,
+            this.onTypeInstantiateToBounds,
+            SubtypeCheckMode.ignoringNullabilities);
         if (thisIsSubtype && !thisIsSupertype) {
           // This is subtype of other and not vice-versa.
           return true;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
index f8f0ff5..bb90d9d 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
@@ -5,6 +5,8 @@
 import 'package:kernel/ast.dart'
     show DartType, Expression, TypeParameterType, VariableDeclaration;
 
+import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+
 import '../fasta_codes.dart' show templateInternalProblemStackNotEmpty;
 
 import '../problems.dart' show internalProblem;
@@ -682,16 +684,18 @@
     // What we do now depends on the relationship between the previous type of
     // the variable and the type we are checking against.
     DartType previousType = previousPromotedType ?? variable.type;
-    if (promoter.typeSchemaEnvironment.isSubtypeOf(checkedType, previousType)) {
+    if (promoter.typeSchemaEnvironment.isSubtypeOf(
+        checkedType, previousType, SubtypeCheckMode.ignoringNullabilities)) {
       // The type we are checking against is a subtype of the previous type of
       // the variable, so this is a refinement; we can promote.
       return checkedType;
     } else if (previousType is TypeParameterType &&
-        promoter.typeSchemaEnvironment
-            .isSubtypeOf(checkedType, previousType.bound)) {
+        promoter.typeSchemaEnvironment.isSubtypeOf(checkedType,
+            previousType.bound, SubtypeCheckMode.ignoringNullabilities)) {
       // The type we are checking against is a subtype of the bound of the
       // previous type of the variable; we can promote the bound.
-      return new TypeParameterType(previousType.parameter, checkedType);
+      return new TypeParameterType(
+          previousType.parameter, checkedType, previousType.nullability);
     } else {
       // The types aren't sufficiently related; we can't promote.
       return previousPromotedType;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
index 1634efb..6a2aa4e 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema.dart
@@ -10,6 +10,7 @@
         FunctionType,
         InterfaceType,
         NamedType,
+        Nullability,
         TypedefType,
         Visitor;
 
@@ -18,8 +19,6 @@
 import 'package:kernel/text/ast_to_text.dart'
     show Annotator, NameSystem, Printer, globalDebuggingNames;
 
-import '../problems.dart' show unsupported;
-
 /// Determines whether a type schema contains `?` somewhere inside it.
 bool isKnown(DartType schema) => schema.accept(new _IsKnownVisitor());
 
@@ -60,7 +59,7 @@
 /// purely part of the local inference process.
 class UnknownType extends DartType {
   @override
-  get nullability => unsupported("nullability", -1, null);
+  Nullability get nullability => null;
 
   const UnknownType();
 
@@ -81,6 +80,9 @@
 
   @override
   visitChildren(Visitor<dynamic> v) {}
+
+  @override
+  UnknownType withNullability(Nullability nullability) => this;
 }
 
 /// Visitor that computes [isKnown].
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 5f8280e..8339567 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
@@ -19,6 +19,8 @@
 
 import 'package:kernel/type_algebra.dart' show Substitution;
 
+import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
+
 import 'package:kernel/src/hierarchy_based_type_environment.dart'
     show HierarchyBasedTypeEnvironment;
 
@@ -267,7 +269,8 @@
       if (success && !hasOmittedBound(typeParam)) {
         // If everything else succeeded, check the `extends` constraint.
         DartType extendsConstraint = typeParamBound;
-        success = isSubtypeOf(inferred, extendsConstraint);
+        success = isSubtypeOf(inferred, extendsConstraint,
+            SubtypeCheckMode.ignoringNullabilities);
       }
 
       if (!success) {
@@ -288,10 +291,11 @@
   }
 
   @override
-  bool isSubtypeOf(DartType subtype, DartType supertype) {
+  bool isSubtypeOf(
+      DartType subtype, DartType supertype, SubtypeCheckMode mode) {
     if (subtype is UnknownType) return true;
     if (subtype == Null && supertype is UnknownType) return true;
-    return super.isSubtypeOf(subtype, supertype);
+    return super.isSubtypeOf(subtype, supertype, mode);
   }
 
   bool isEmptyContext(DartType context) {
@@ -359,8 +363,10 @@
 
   /// Determine if the given [type] satisfies the given type [constraint].
   bool typeSatisfiesConstraint(DartType type, TypeConstraint constraint) {
-    return isSubtypeOf(constraint.lower, type) &&
-        isSubtypeOf(type, constraint.upper);
+    return isSubtypeOf(
+            constraint.lower, type, SubtypeCheckMode.ignoringNullabilities) &&
+        isSubtypeOf(
+            type, constraint.upper, SubtypeCheckMode.ignoringNullabilities);
   }
 
   DartType _inferTypeParameterFromAll(DartType typeFromContextInference,
diff --git a/pkg/front_end/lib/src/testing/id_extractor.dart b/pkg/front_end/lib/src/testing/id_extractor.dart
index 0afbb82..a7be604 100644
--- a/pkg/front_end/lib/src/testing/id_extractor.dart
+++ b/pkg/front_end/lib/src/testing/id_extractor.dart
@@ -61,9 +61,8 @@
 
   DataExtractor(this.actualMap);
 
-  void computeForLibrary(Library library, {bool useFileUri: false}) {
-    LibraryId id =
-        new LibraryId(useFileUri ? library.fileUri : library.importUri);
+  void computeForLibrary(Library library) {
+    LibraryId id = new LibraryId(library.fileUri);
     T value = computeLibraryValue(id, library);
     registerValue(library.fileUri, null, id, value, library);
   }
diff --git a/pkg/front_end/lib/src/testing/id_testing.dart b/pkg/front_end/lib/src/testing/id_testing.dart
index 6aba9fb..3c49ea0 100644
--- a/pkg/front_end/lib/src/testing/id_testing.dart
+++ b/pkg/front_end/lib/src/testing/id_testing.dart
@@ -214,6 +214,8 @@
             entry;
       }
     }
+    assert(
+        mainTestFile != null, "No 'main.dart' test file found for $testFile.");
   }
 
   String annotatedCode = new File.fromUri(mainTestFile.uri).readAsStringSync();
diff --git a/pkg/front_end/lib/src/testing/id_testing_helper.dart b/pkg/front_end/lib/src/testing/id_testing_helper.dart
index ec92375..68aa64d 100644
--- a/pkg/front_end/lib/src/testing/id_testing_helper.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_helper.dart
@@ -8,6 +8,7 @@
 import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
 import '../api_prototype/terminal_color_support.dart'
     show printDiagnosticMessage;
+import '../base/common.dart';
 import '../fasta/messages.dart' show FormattedMessage;
 import '../fasta/severity.dart' show Severity;
 import '../kernel_generator_impl.dart' show InternalCompilerResult;
@@ -42,8 +43,10 @@
   final String marker;
   final String name;
   final Map<ExperimentalFlag, bool> experimentalFlags;
+  final Uri librariesSpecificationUri;
 
-  const TestConfig(this.marker, this.name, {this.experimentalFlags = const {}});
+  const TestConfig(this.marker, this.name,
+      {this.experimentalFlags = const {}, this.librariesSpecificationUri});
 
   void customizeCompilerOptions(CompilerOptions options) {}
 }
@@ -180,6 +183,7 @@
 /// Creates a test runner for [dataComputer] on [testedConfigs].
 RunTestFunction runTestFor<T>(
     DataComputer<T> dataComputer, List<TestConfig> testedConfigs) {
+  retainDataForTesting = true;
   return (TestData testData,
       {bool testAfterFailures, bool verbose, bool succinct, bool printCode}) {
     return runTest(testData, dataComputer, testedConfigs,
@@ -242,6 +246,13 @@
   };
   options.debugDump = printCode;
   options.experimentalFlags.addAll(config.experimentalFlags);
+  if (config.librariesSpecificationUri != null) {
+    Set<Uri> testFiles =
+        testData.memorySourceFiles.keys.map(createUriForFileName).toSet();
+    if (testFiles.contains(config.librariesSpecificationUri)) {
+      options.librariesSpecificationUri = config.librariesSpecificationUri;
+    }
+  }
   config.customizeCompilerOptions(options);
   InternalCompilerResult compilerResult = await compileScript(
       testData.memorySourceFiles,
diff --git a/pkg/front_end/lib/src/testing/id_testing_utils.dart b/pkg/front_end/lib/src/testing/id_testing_utils.dart
index d32d8f5..0c98653 100644
--- a/pkg/front_end/lib/src/testing/id_testing_utils.dart
+++ b/pkg/front_end/lib/src/testing/id_testing_utils.dart
@@ -62,7 +62,7 @@
       (Extension extension) => extension.name == extensionName, orElse: () {
     if (required) {
       throw new ArgumentError(
-          "Extension '$extensionName' not found in '$library'.");
+          "Extension '$extensionName' not found in '${library.importUri}'.");
     }
     return null;
   });
@@ -151,7 +151,7 @@
       lookupClassBuilder(compilerResult, cls, required: required);
   MemberBuilder memberBuilder;
   if (classBuilder != null) {
-    if (member is Constructor) {
+    if (member is Constructor || member is Procedure && member.isFactory) {
       memberBuilder = classBuilder.constructors.local[memberName];
     } else if (member is Procedure && member.isSetter) {
       memberBuilder = classBuilder.scope.setters[memberName];
@@ -527,9 +527,6 @@
 /// Returns a textual representation of [descriptor] to be used in testing.
 String extensionMethodDescriptorToText(ExtensionMemberDescriptor descriptor) {
   StringBuffer sb = new StringBuffer();
-  if (descriptor.isExternal) {
-    sb.write('external ');
-  }
   if (descriptor.isStatic) {
     sb.write('static ');
   }
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 34bb332..ccc99a2 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -215,6 +215,7 @@
 ExtensionDeclaresAbstractMember/example: Fail
 ExtensionDeclaresConstructor/example: Fail
 ExtensionDeclaresInstanceField/example: Fail
+ExtensionMemberConflictsWithObjectMember/analyzerCode: Fail
 ExtraneousModifier/part_wrapped_script1: Fail
 ExtraneousModifier/part_wrapped_script2: Fail
 ExtraneousModifier/part_wrapped_script3: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 2782772..e67853d 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -457,8 +457,8 @@
 
 EqualityCannotBeEqualityOperand:
   index: 1
-  template: "An equality expression can't be an operand of another equality expression."
-  tip: "Try re-writing the expression."
+  template: "A comparison expression can't be an operand of another comparison expression."
+  tip: "Try putting parentheses around one of the comparisons."
   analyzerCode: ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND
   script:
     - "main() { var b = a < b < c; }"
@@ -703,7 +703,7 @@
 ExternalField:
   index: 50
   template: "Fields can't be declared to be 'external'."
-  tip: "Try removing the keyword 'external'."
+  tip: "Try removing the keyword 'external', or replacing the field by an external getter and/or setter."
   analyzerCode: ParserErrorCode.EXTERNAL_FIELD
   script:
     - "class C { external var f; }"
@@ -926,7 +926,7 @@
   script: "main() sync {}"
 
 InvalidVoid:
-  template: "Type 'void' can't be used here because it isn't a return type."
+  template: "Type 'void' can't be used here."
   tip: "Try removing 'void' keyword or replace it with 'var', 'final', or a type."
   analyzerCode: EXPECTED_TYPE_NAME
   script:
@@ -943,7 +943,7 @@
 
 FieldInitializedOutsideDeclaringClass:
   index: 88
-  template: "A field can only be initialized in it's declaring class"
+  template: "A field can only be initialized in its declaring class"
   tip: "Try passing a value into the superclass constructor, or moving the initialization into the constructor body."
   analyzerCode: ParserErrorCode.FIELD_INITIALIZED_OUTSIDE_DECLARING_CLASS
   script:
@@ -1137,7 +1137,6 @@
 
 BuiltInIdentifierAsType:
   template: "The built-in identifier '#lexeme' can't be used as a type."
-  tip: "Try correcting the name to match an existing type."
   analyzerCode: BUILT_IN_IDENTIFIER_AS_TYPE
 
 BuiltInIdentifierInDeclaration:
@@ -1265,12 +1264,12 @@
 
 ConstFieldWithoutInitializer:
   template: "The const variable '#name' must be initialized."
-  tip: "Try adding an initializer ('= <expression>') to the declaration."
+  tip: "Try adding an initializer ('= expression') to the declaration."
   analyzerCode: CONST_NOT_INITIALIZED
 
 FinalFieldWithoutInitializer:
   template: "The final variable '#name' must be initialized."
-  tip: "Try adding an initializer ('= <expression>') to the declaration."
+  tip: "Try adding an initializer ('= expression') to the declaration."
   analyzerCode: FINAL_NOT_INITIALIZED
 
 MetadataTypeArguments:
@@ -1718,7 +1717,7 @@
 MissingPrefixInDeferredImport:
   index: 30
   template: "Deferred imports should have a prefix."
-  tip: "Try adding a prefix to the import."
+  tip: "Try adding a prefix to the import by adding an 'as' clause."
   analyzerCode: ParserErrorCode.MISSING_PREFIX_IN_DEFERRED_IMPORT
 
 DeferredAfterPrefix:
@@ -1936,6 +1935,13 @@
   template: "This is the type variable."
   severity: CONTEXT
 
+ExtensionMemberConflictsWithObjectMember:
+  template: "This extension member conflicts with Object member '#name'."
+  script:
+    extension Extension on String {
+      int get noSuchMethod => 42;
+    }
+
 DeclaredMemberConflictsWithInheritedMember:
   template: "Can't declare a member that conflicts with an inherited one."
   analyzerCode: DECLARED_MEMBER_CONFLICTS_WITH_INHERITED
@@ -2781,7 +2787,7 @@
 
 MissingAssignableSelector:
   index: 35
-  template: "Missing selector such as '.<identifier>' or '[0]'."
+  template: "Missing selector such as '.identifier' or '[0]'."
   tip: "Try adding a selector."
   analyzerCode: ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR
   script:
@@ -2833,12 +2839,10 @@
 
 ArgumentTypeNotAssignable:
   template: "The argument type '#type' can't be assigned to the parameter type '#type2'."
-  tip: "Try changing the type of the parameter, or casting the argument to '#type2'."
   analyzerCode: ARGUMENT_TYPE_NOT_ASSIGNABLE
 
 InvalidAssignment:
   template: "A value of type '#type' can't be assigned to a variable of type '#type2'."
-  tip: "Try changing the type of the left hand side, or casting the right hand side to '#type2'."
   analyzerCode: INVALID_ASSIGNMENT
   script: >
     main() {
@@ -3157,7 +3161,7 @@
 
 CantUsePrefixWithNullAware:
   template: "A prefix can't be used with null-aware operators."
-  tip: "It should be safe to remove the '?' as a prefix is never null."
+  tip: "Try replacing '?.' with '.'"
   analyzerCode: PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT
   script: |
     import "dart:core" as prefix;
@@ -3418,7 +3422,7 @@
     class C = Object with M;
 
 GenericFunctionTypeUsedAsActualTypeArgument:
-  template: "Unexpected generic function type found in a type argument."
+  template: "A generic function type can't be used as a type argument."
   tip: "Try using a non-generic function type."
   analyzerCode: GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT
   script:
@@ -3434,7 +3438,7 @@
       }
 
 GenericFunctionTypeInferredAsActualTypeArgument:
-  template: "Unexpected generic function type '#type' inferred as a type argument."
+  template: "Generic function type '#type' inferred as a type argument."
   tip: "Try providing a non-generic function type explicitly."
   analyzerCode: GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT
   script:
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.intertwined.expect
new file mode 100644
index 0000000..7bf2cde
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex.dart.intertwined.expect
@@ -0,0 +1,88 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, foo)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(foo)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(foo, expression)
+                              listener: handleNoTypeArguments(.)
+                              parseArgumentsOpt(foo)
+                                listener: handleNoArguments(.)
+                              listener: handleSend(foo, .)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(bar, expressionContinuation)
+                            listener: handleNoTypeArguments(!)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(!)
+                            listener: handleSend(bar, !)
+                      listener: endBinaryExpression(.)
+                      listener: handleNonNullAssertExpression(!)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(baz, expressionContinuation)
+                            listener: handleNoTypeArguments([)
+                            parseArgumentsOpt(baz)
+                              listener: handleNoArguments([)
+                            listener: handleSend(baz, [)
+                      listener: endBinaryExpression(.)
+                      parseArgumentOrIndexStar(baz, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..69fcc2c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckBeforeIndex_with_parens.dart.intertwined.expect
@@ -0,0 +1,99 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(foo, expression)
+                                                listener: handleNoTypeArguments(.)
+                                                parseArgumentsOpt(foo)
+                                                  listener: handleNoArguments(.)
+                                                listener: handleSend(foo, .)
+                                        parsePrimary(., expressionContinuation)
+                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                            parseSend(., expressionContinuation)
+                                              ensureIdentifier(., expressionContinuation)
+                                                listener: handleIdentifier(bar, expressionContinuation)
+                                              listener: handleNoTypeArguments())
+                                              parseArgumentsOpt(bar)
+                                                listener: handleNoArguments())
+                                              listener: handleSend(bar, ))
+                                        listener: endBinaryExpression(.)
+                                    ensureCloseParen(bar, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: handleNonNullAssertExpression(!)
+                        parsePrimary(., expressionContinuation)
+                          parseSendOrFunctionLiteral(., expressionContinuation)
+                            parseSend(., expressionContinuation)
+                              ensureIdentifier(., expressionContinuation)
+                                listener: handleIdentifier(baz, expressionContinuation)
+                              listener: handleNoTypeArguments([)
+                              parseArgumentsOpt(baz)
+                                listener: handleNoArguments([)
+                              listener: handleSend(baz, [)
+                        listener: endBinaryExpression(.)
+                        parseArgumentOrIndexStar(baz, Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.intertwined.expect
new file mode 100644
index 0000000..109f304
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex.dart.intertwined.expect
@@ -0,0 +1,68 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, obj)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(obj)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(obj, expression)
+                              listener: handleNoTypeArguments(!)
+                              parseArgumentsOpt(obj)
+                                listener: handleNoArguments(!)
+                              listener: handleSend(obj, !)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.intertwined.expect
new file mode 100644
index 0000000..0b43b40
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2.dart.intertwined.expect
@@ -0,0 +1,83 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, obj)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(obj)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(obj, expression)
+                              listener: handleNoTypeArguments(!)
+                              parseArgumentsOpt(obj)
+                                listener: handleNoArguments(!)
+                              listener: handleSend(obj, !)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg2, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg2)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg2, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..6c15e07
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex2_with_parens.dart.intertwined.expect
@@ -0,0 +1,114 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              parseParenthesizedExpression(()
+                                                parseExpressionInParenthesis(()
+                                                  parseExpressionInParenthesisRest(()
+                                                    parseExpression(()
+                                                      parsePrecedenceExpression((, 1, true)
+                                                        parseUnaryExpression((, true)
+                                                          parsePrimary((, expression)
+                                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                                              parseParenthesizedExpression(()
+                                                                parseExpressionInParenthesis(()
+                                                                  parseExpressionInParenthesisRest(()
+                                                                    parseExpression(()
+                                                                      parsePrecedenceExpression((, 1, true)
+                                                                        parseUnaryExpression((, true)
+                                                                          parsePrimary((, expression)
+                                                                            parseSendOrFunctionLiteral((, expression)
+                                                                              parseSend((, expression)
+                                                                                ensureIdentifier((, expression)
+                                                                                  listener: handleIdentifier(obj, expression)
+                                                                                listener: handleNoTypeArguments(!)
+                                                                                parseArgumentsOpt(obj)
+                                                                                  listener: handleNoArguments(!)
+                                                                                listener: handleSend(obj, !)
+                                                                        listener: handleNonNullAssertExpression(!)
+                                                                    ensureCloseParen(!, ()
+                                                                listener: handleParenthesizedExpression(()
+                                                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                                                          parseExpression([)
+                                                            parsePrecedenceExpression([, 1, true)
+                                                              parseUnaryExpression([, true)
+                                                                parsePrimary([, expression)
+                                                                  parseSendOrFunctionLiteral([, expression)
+                                                                    parseSend([, expression)
+                                                                      ensureIdentifier([, expression)
+                                                                        listener: handleIdentifier(arg, expression)
+                                                                      listener: handleNoTypeArguments(])
+                                                                      parseArgumentsOpt(arg)
+                                                                        listener: handleNoArguments(])
+                                                                      listener: handleSend(arg, ])
+                                                          listener: handleIndexedExpression([, ])
+                                                    ensureCloseParen(], ()
+                                                listener: handleParenthesizedExpression(()
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg2, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg2)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg2, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.intertwined.expect
new file mode 100644
index 0000000..f3b48e4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3.dart.intertwined.expect
@@ -0,0 +1,78 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, foo)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(foo)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(foo, expression)
+                              listener: handleNoTypeArguments(.)
+                              parseArgumentsOpt(foo)
+                                listener: handleNoArguments(.)
+                              listener: handleSend(foo, .)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(bar, expressionContinuation)
+                            listener: handleNoTypeArguments(!)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(!)
+                            listener: handleSend(bar, !)
+                      listener: endBinaryExpression(.)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..c349f09
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex3_with_parens.dart.intertwined.expect
@@ -0,0 +1,89 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(foo, expression)
+                                                listener: handleNoTypeArguments(.)
+                                                parseArgumentsOpt(foo)
+                                                  listener: handleNoArguments(.)
+                                                listener: handleSend(foo, .)
+                                        parsePrimary(., expressionContinuation)
+                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                            parseSend(., expressionContinuation)
+                                              ensureIdentifier(., expressionContinuation)
+                                                listener: handleIdentifier(bar, expressionContinuation)
+                                              listener: handleNoTypeArguments())
+                                              parseArgumentsOpt(bar)
+                                                listener: handleNoArguments())
+                                              listener: handleSend(bar, ))
+                                        listener: endBinaryExpression(.)
+                                    ensureCloseParen(bar, ()
+                                listener: handleParenthesizedExpression(()
+                        listener: handleNonNullAssertExpression(!)
+                        parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.intertwined.expect
new file mode 100644
index 0000000..89095e5
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4.dart.intertwined.expect
@@ -0,0 +1,79 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, foo)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(foo)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(foo, expression)
+                              listener: handleNoTypeArguments(!)
+                              parseArgumentsOpt(foo)
+                                listener: handleNoArguments(!)
+                              listener: handleSend(foo, !)
+                      listener: handleNonNullAssertExpression(!)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(bar, expressionContinuation)
+                            listener: handleNoTypeArguments(!)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(!)
+                            listener: handleSend(bar, !)
+                      listener: endBinaryExpression(.)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..4e8d872
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex4_with_parens.dart.intertwined.expect
@@ -0,0 +1,100 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              parseParenthesizedExpression(()
+                                                parseExpressionInParenthesis(()
+                                                  parseExpressionInParenthesisRest(()
+                                                    parseExpression(()
+                                                      parsePrecedenceExpression((, 1, true)
+                                                        parseUnaryExpression((, true)
+                                                          parsePrimary((, expression)
+                                                            parseSendOrFunctionLiteral((, expression)
+                                                              parseSend((, expression)
+                                                                ensureIdentifier((, expression)
+                                                                  listener: handleIdentifier(foo, expression)
+                                                                listener: handleNoTypeArguments(!)
+                                                                parseArgumentsOpt(foo)
+                                                                  listener: handleNoArguments(!)
+                                                                listener: handleSend(foo, !)
+                                                        listener: handleNonNullAssertExpression(!)
+                                                    ensureCloseParen(!, ()
+                                                listener: handleParenthesizedExpression(()
+                                        parsePrimary(., expressionContinuation)
+                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                            parseSend(., expressionContinuation)
+                                              ensureIdentifier(., expressionContinuation)
+                                                listener: handleIdentifier(bar, expressionContinuation)
+                                              listener: handleNoTypeArguments(!)
+                                              parseArgumentsOpt(bar)
+                                                listener: handleNoArguments(!)
+                                              listener: handleSend(bar, !)
+                                        listener: endBinaryExpression(.)
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.intertwined.expect
new file mode 100644
index 0000000..c6b3abd
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5.dart.intertwined.expect
@@ -0,0 +1,93 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, foo)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(foo)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(foo, expression)
+                              listener: handleNoTypeArguments(.)
+                              parseArgumentsOpt(foo)
+                                listener: handleNoArguments(.)
+                              listener: handleSend(foo, .)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(bar, expressionContinuation)
+                            listener: handleNoTypeArguments(!)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(!)
+                            listener: handleSend(bar, !)
+                      listener: endBinaryExpression(.)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg2, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg2)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg2, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..1f1f0bf
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex5_with_parens.dart.intertwined.expect
@@ -0,0 +1,124 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              parseParenthesizedExpression(()
+                                                parseExpressionInParenthesis(()
+                                                  parseExpressionInParenthesisRest(()
+                                                    parseExpression(()
+                                                      parsePrecedenceExpression((, 1, true)
+                                                        parseUnaryExpression((, true)
+                                                          parsePrimary((, expression)
+                                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                                              parseParenthesizedExpression(()
+                                                                parseExpressionInParenthesis(()
+                                                                  parseExpressionInParenthesisRest(()
+                                                                    parseExpression(()
+                                                                      parsePrecedenceExpression((, 1, true)
+                                                                        parseUnaryExpression((, true)
+                                                                          parsePrimary((, expression)
+                                                                            parseSendOrFunctionLiteral((, expression)
+                                                                              parseSend((, expression)
+                                                                                ensureIdentifier((, expression)
+                                                                                  listener: handleIdentifier(foo, expression)
+                                                                                listener: handleNoTypeArguments(.)
+                                                                                parseArgumentsOpt(foo)
+                                                                                  listener: handleNoArguments(.)
+                                                                                listener: handleSend(foo, .)
+                                                                        parsePrimary(., expressionContinuation)
+                                                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                                                            parseSend(., expressionContinuation)
+                                                                              ensureIdentifier(., expressionContinuation)
+                                                                                listener: handleIdentifier(bar, expressionContinuation)
+                                                                              listener: handleNoTypeArguments(!)
+                                                                              parseArgumentsOpt(bar)
+                                                                                listener: handleNoArguments(!)
+                                                                              listener: handleSend(bar, !)
+                                                                        listener: endBinaryExpression(.)
+                                                                        listener: handleNonNullAssertExpression(!)
+                                                                    ensureCloseParen(!, ()
+                                                                listener: handleParenthesizedExpression(()
+                                                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                                                          parseExpression([)
+                                                            parsePrecedenceExpression([, 1, true)
+                                                              parseUnaryExpression([, true)
+                                                                parsePrimary([, expression)
+                                                                  parseSendOrFunctionLiteral([, expression)
+                                                                    parseSend([, expression)
+                                                                      ensureIdentifier([, expression)
+                                                                        listener: handleIdentifier(arg, expression)
+                                                                      listener: handleNoTypeArguments(])
+                                                                      parseArgumentsOpt(arg)
+                                                                        listener: handleNoArguments(])
+                                                                      listener: handleSend(arg, ])
+                                                          listener: handleIndexedExpression([, ])
+                                                    ensureCloseParen(], ()
+                                                listener: handleParenthesizedExpression(()
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg2, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg2)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg2, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.intertwined.expect
new file mode 100644
index 0000000..795f82d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6.dart.intertwined.expect
@@ -0,0 +1,94 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, foo)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(foo)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(foo, expression)
+                              listener: handleNoTypeArguments(!)
+                              parseArgumentsOpt(foo)
+                                listener: handleNoArguments(!)
+                              listener: handleSend(foo, !)
+                      listener: handleNonNullAssertExpression(!)
+                      parsePrimary(., expressionContinuation)
+                        parseSendOrFunctionLiteral(., expressionContinuation)
+                          parseSend(., expressionContinuation)
+                            ensureIdentifier(., expressionContinuation)
+                              listener: handleIdentifier(bar, expressionContinuation)
+                            listener: handleNoTypeArguments(!)
+                            parseArgumentsOpt(bar)
+                              listener: handleNoArguments(!)
+                            listener: handleSend(bar, !)
+                      listener: endBinaryExpression(.)
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg, ])
+                        listener: handleIndexedExpression([, ])
+                      listener: handleNonNullAssertExpression(!)
+                      parseArgumentOrIndexStar(!, Instance of 'NoTypeParamOrArg')
+                        parseExpression([)
+                          parsePrecedenceExpression([, 1, true)
+                            parseUnaryExpression([, true)
+                              parsePrimary([, expression)
+                                parseSendOrFunctionLiteral([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      listener: handleIdentifier(arg2, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt(arg2)
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(arg2, ])
+                        listener: handleIndexedExpression([, ])
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..41a6cb6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex6_with_parens.dart.intertwined.expect
@@ -0,0 +1,135 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              parseParenthesizedExpression(()
+                                                parseExpressionInParenthesis(()
+                                                  parseExpressionInParenthesisRest(()
+                                                    parseExpression(()
+                                                      parsePrecedenceExpression((, 1, true)
+                                                        parseUnaryExpression((, true)
+                                                          parsePrimary((, expression)
+                                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                                              parseParenthesizedExpression(()
+                                                                parseExpressionInParenthesis(()
+                                                                  parseExpressionInParenthesisRest(()
+                                                                    parseExpression(()
+                                                                      parsePrecedenceExpression((, 1, true)
+                                                                        parseUnaryExpression((, true)
+                                                                          parsePrimary((, expression)
+                                                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                                                              parseParenthesizedExpression(()
+                                                                                parseExpressionInParenthesis(()
+                                                                                  parseExpressionInParenthesisRest(()
+                                                                                    parseExpression(()
+                                                                                      parsePrecedenceExpression((, 1, true)
+                                                                                        parseUnaryExpression((, true)
+                                                                                          parsePrimary((, expression)
+                                                                                            parseSendOrFunctionLiteral((, expression)
+                                                                                              parseSend((, expression)
+                                                                                                ensureIdentifier((, expression)
+                                                                                                  listener: handleIdentifier(foo, expression)
+                                                                                                listener: handleNoTypeArguments(!)
+                                                                                                parseArgumentsOpt(foo)
+                                                                                                  listener: handleNoArguments(!)
+                                                                                                listener: handleSend(foo, !)
+                                                                                        listener: handleNonNullAssertExpression(!)
+                                                                                    ensureCloseParen(!, ()
+                                                                                listener: handleParenthesizedExpression(()
+                                                                        parsePrimary(., expressionContinuation)
+                                                                          parseSendOrFunctionLiteral(., expressionContinuation)
+                                                                            parseSend(., expressionContinuation)
+                                                                              ensureIdentifier(., expressionContinuation)
+                                                                                listener: handleIdentifier(bar, expressionContinuation)
+                                                                              listener: handleNoTypeArguments(!)
+                                                                              parseArgumentsOpt(bar)
+                                                                                listener: handleNoArguments(!)
+                                                                              listener: handleSend(bar, !)
+                                                                        listener: endBinaryExpression(.)
+                                                                        listener: handleNonNullAssertExpression(!)
+                                                                    ensureCloseParen(!, ()
+                                                                listener: handleParenthesizedExpression(()
+                                                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                                                          parseExpression([)
+                                                            parsePrecedenceExpression([, 1, true)
+                                                              parseUnaryExpression([, true)
+                                                                parsePrimary([, expression)
+                                                                  parseSendOrFunctionLiteral([, expression)
+                                                                    parseSend([, expression)
+                                                                      ensureIdentifier([, expression)
+                                                                        listener: handleIdentifier(arg, expression)
+                                                                      listener: handleNoTypeArguments(])
+                                                                      parseArgumentsOpt(arg)
+                                                                        listener: handleNoArguments(])
+                                                                      listener: handleSend(arg, ])
+                                                          listener: handleIndexedExpression([, ])
+                                                    ensureCloseParen(], ()
+                                                listener: handleParenthesizedExpression(()
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg2, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg2)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg2, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect
new file mode 100644
index 0000000..0f8729a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/nnbd/nullCheckOnIndex_with_parens.dart.intertwined.expect
@@ -0,0 +1,79 @@
+parseUnit(f)
+  skipErrorTokens(f)
+  listener: beginCompilationUnit(f)
+  syntheticPreviousToken(f)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(f)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(f)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, f)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifier(, topLevelFunctionDeclaration)
+          listener: handleIdentifier(f, topLevelFunctionDeclaration)
+        parseMethodTypeVar(f)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(f, MemberKind.TopLevelMethod)
+            parseFormalParametersRest((, MemberKind.TopLevelMethod)
+              listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+              listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          listener: beginBlockFunctionBody({)
+          notEofOrValue(}, ()
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclaration({, false)
+                parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                  looksLikeLocalFunction(()
+                  parseExpressionStatement({)
+                    parseExpression({)
+                      parsePrecedenceExpression({, 1, true)
+                        parseUnaryExpression({, true)
+                          parsePrimary({, expression)
+                            parseParenthesizedExpressionOrFunctionLiteral({)
+                              parseParenthesizedExpression({)
+                                parseExpressionInParenthesis({)
+                                  parseExpressionInParenthesisRest(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseSendOrFunctionLiteral((, expression)
+                                              parseSend((, expression)
+                                                ensureIdentifier((, expression)
+                                                  listener: handleIdentifier(obj, expression)
+                                                listener: handleNoTypeArguments(!)
+                                                parseArgumentsOpt(obj)
+                                                  listener: handleNoArguments(!)
+                                                listener: handleSend(obj, !)
+                                        listener: handleNonNullAssertExpression(!)
+                                    ensureCloseParen(!, ()
+                                listener: handleParenthesizedExpression(()
+                        parseArgumentOrIndexStar(), Instance of 'NoTypeParamOrArg')
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(arg, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(arg)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(arg, ])
+                          listener: handleIndexedExpression([, ])
+                    ensureSemicolon(])
+                    listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(1, {, })
+        listener: endTopLevelMethod(f, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(f)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/test/extensions/data/as_show/lib.dart b/pkg/front_end/test/extensions/data/as_show/lib.dart
new file mode 100644
index 0000000..e89ef0c
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/lib.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, 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.
+
+/*library: scope=[Extension1]*/
+
+/*class: Extension1:
+ builder-name=Extension1,
+ builder-onType=String,
+ extension-members=[
+  method1=Extension1|method1,
+  tearoff method1=Extension1|get#method1],
+ extension-name=Extension1,
+ extension-onType=String
+*/
+extension Extension1 on String {
+  /*member: Extension1|method1:
+   builder-name=method1,
+   builder-params=[#this],
+   member-name=Extension1|method1,
+   member-params=[#this]
+  */
+  method1() {}
+
+  /*member: Extension1|get#method1:
+   builder-name=method1,
+   builder-params=[#this],
+   member-name=Extension1|get#method1,
+   member-params=[#this]*/
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/data/as_show/libraries.json b/pkg/front_end/test/extensions/data/as_show/libraries.json
new file mode 100644
index 0000000..7a584cb
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/libraries.json
@@ -0,0 +1,9 @@
+{
+  "none": {
+    "libraries": {
+      "test": {
+        "uri": "origin.dart"
+      }
+    }
+  }
+}
diff --git a/pkg/front_end/test/extensions/data/as_show/main.dart b/pkg/front_end/test/extensions/data/as_show/main.dart
new file mode 100644
index 0000000..2a7d2d1
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/main.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2019, 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.
+
+/*library: scope=[lib.dart.Extension1,origin.dart.Extension2]*/
+
+import 'lib.dart' as lib1;
+import 'lib.dart' show Extension1;
+
+// ignore: uri_does_not_exist
+import 'dart:test' as lib2;
+// ignore: uri_does_not_exist
+import 'dart:test' show Extension2;
+
+main() {
+  "".method1();
+  Extension1("").method1();
+  "".method2();
+  Extension2("").method2();
+}
diff --git a/pkg/front_end/test/extensions/data/as_show/origin.dart b/pkg/front_end/test/extensions/data/as_show/origin.dart
new file mode 100644
index 0000000..1b36bb9
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/as_show/origin.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2019, 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.
+
+/*library: scope=[Extension2]*/
+
+/*class: Extension2:
+ builder-name=Extension2,
+ builder-onType=String,
+ extension-members=[
+  method2=Extension2|method2,
+  tearoff method2=Extension2|get#method2],
+ extension-name=Extension2,
+ extension-onType=String
+*/
+extension Extension2 on String {
+/*member: Extension2|method2:
+   builder-name=method2,
+   builder-params=[#this],
+   member-name=Extension2|method2,
+   member-params=[#this]
+  */
+method2() {}
+
+/*member: Extension2|get#method2:
+   builder-name=method2,
+   builder-params=[#this],
+   member-name=Extension2|get#method2,
+   member-params=[#this]*/
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/data/patching/libraries.json b/pkg/front_end/test/extensions/data/patching/libraries.json
new file mode 100644
index 0000000..a697508
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/libraries.json
@@ -0,0 +1,12 @@
+{
+  "none": {
+    "libraries": {
+      "test": {
+        "patches": [
+          "patch.dart"
+        ],
+        "uri": "origin.dart"
+      }
+    }
+  }
+}
diff --git a/pkg/front_end/test/extensions/data/patching/main.dart b/pkg/front_end/test/extensions/data/patching/main.dart
new file mode 100644
index 0000000..9599059
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/main.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2019, 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.
+
+/*library: scope=[origin.dart.Extension,origin.dart.GenericExtension]*/
+
+// ignore: uri_does_not_exist
+import 'dart:test';
+
+main() {
+  "".instanceMethod();
+  "".genericInstanceMethod<int>(0);
+  "".instanceProperty = "".instanceProperty;
+  Extension.staticMethod();
+  Extension.genericStaticMethod<int>(0);
+  Extension.staticProperty = Extension.staticProperty;
+  true.instanceMethod();
+  true.genericInstanceMethod<int>(0);
+  true.instanceProperty = true.instanceProperty;
+  GenericExtension.staticMethod();
+  GenericExtension.genericStaticMethod<int>(0);
+  GenericExtension.staticProperty = GenericExtension.staticProperty;
+}
diff --git a/pkg/front_end/test/extensions/data/patching/origin.dart b/pkg/front_end/test/extensions/data/patching/origin.dart
new file mode 100644
index 0000000..1a5b69e
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/origin.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2019, 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.
+
+/*library: scope=[Extension,GenericExtension]*/
+
+/*class: Extension:
+ builder-name=Extension,
+ builder-onType=String,
+ extension-members=[
+  genericInstanceMethod=Extension|genericInstanceMethod,
+  getter instanceProperty=Extension|get#instanceProperty,
+  instanceMethod=Extension|instanceMethod,
+  setter instanceProperty=Extension|set#instanceProperty,
+  static genericStaticMethod=Extension|genericStaticMethod,
+  static getter staticProperty=Extension|staticProperty,
+  static setter staticProperty=Extension|staticProperty=,
+  static staticMethod=Extension|staticMethod,
+  tearoff genericInstanceMethod=Extension|get#genericInstanceMethod,
+  tearoff instanceMethod=Extension|get#instanceMethod,
+ ],
+ extension-name=Extension,
+ extension-onType=String
+*/
+extension Extension on String {
+  /*member: Extension|get#instanceMethod:
+   builder-name=instanceMethod,
+   builder-params=[#this],
+   member-name=Extension|get#instanceMethod,
+   member-params=[#this]
+  */
+  external int instanceMethod();
+
+  /*member: Extension|get#genericInstanceMethod:
+   builder-name=genericInstanceMethod,
+   builder-params=[#this,t],
+   builder-type-params=[T],
+   member-name=Extension|get#genericInstanceMethod,
+   member-params=[#this]
+  */
+  external T genericInstanceMethod<T>(T t);
+
+  external static int staticMethod();
+
+  external static T genericStaticMethod<T>(T t);
+
+  external int get instanceProperty;
+
+  external void set instanceProperty(int value);
+
+  external static int get staticProperty;
+
+  external static void set staticProperty(int value);
+}
+
+/*class: GenericExtension:
+ builder-name=GenericExtension,
+ builder-onType=T,
+ builder-type-params=[T],
+ extension-members=[
+  genericInstanceMethod=GenericExtension|genericInstanceMethod,
+  getter instanceProperty=GenericExtension|get#instanceProperty,
+  instanceMethod=GenericExtension|instanceMethod,
+  setter instanceProperty=GenericExtension|set#instanceProperty,
+  static genericStaticMethod=GenericExtension|genericStaticMethod,
+  static getter staticProperty=GenericExtension|staticProperty,
+  static setter staticProperty=GenericExtension|staticProperty=,
+  static staticMethod=GenericExtension|staticMethod,
+  tearoff genericInstanceMethod=GenericExtension|get#genericInstanceMethod,
+  tearoff instanceMethod=GenericExtension|get#instanceMethod
+  ],
+ extension-name=GenericExtension,
+ extension-onType=T,
+ extension-type-params=[T]
+*/
+extension GenericExtension<T> on T {
+  /*member: GenericExtension|get#instanceMethod:
+   builder-name=instanceMethod,
+   builder-params=[#this],
+   builder-type-params=[T],
+   member-name=GenericExtension|get#instanceMethod,
+   member-params=[#this],
+   member-type-params=[T]
+  */
+  external int instanceMethod();
+
+  /*member: GenericExtension|get#genericInstanceMethod:
+   builder-name=genericInstanceMethod,
+   builder-params=[#this,t],
+   builder-type-params=[T,T],
+   member-name=GenericExtension|get#genericInstanceMethod,
+   member-params=[#this],
+   member-type-params=[#T]
+  */
+  external T genericInstanceMethod<T>(T t);
+
+  external static int staticMethod();
+
+  external static T genericStaticMethod<T>(T t);
+
+  external int get instanceProperty;
+
+  external void set instanceProperty(int value);
+
+  external static int get staticProperty;
+
+  external static void set staticProperty(int value);
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/data/patching/patch.dart b/pkg/front_end/test/extensions/data/patching/patch.dart
new file mode 100644
index 0000000..32edfc4
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/patching/patch.dart
@@ -0,0 +1,163 @@
+// Copyright (c) 2019, 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.
+
+// ignore: import_internal_library
+import 'dart:_internal';
+
+@patch
+extension Extension on String {
+  /*member: Extension|instanceMethod:
+   builder-name=instanceMethod,
+   builder-params=[#this],
+   member-name=Extension|instanceMethod,
+   member-params=[#this]
+  */
+  @patch
+  int instanceMethod() => 42;
+
+  /*member: Extension|genericInstanceMethod:
+   builder-name=genericInstanceMethod,
+   builder-params=[#this,t],
+   builder-type-params=[T],
+   member-name=Extension|genericInstanceMethod,
+   member-params=[#this,t],
+   member-type-params=[T]
+  */
+  @patch
+  T genericInstanceMethod<T>(T t) => t;
+
+  /*member: Extension|staticMethod:
+   builder-name=staticMethod,
+   member-name=Extension|staticMethod
+  */
+  @patch
+  static int staticMethod() => 87;
+
+  /*member: Extension|genericStaticMethod:
+   builder-name=genericStaticMethod,
+   builder-params=[t],
+   builder-type-params=[T],
+   member-name=Extension|genericStaticMethod,
+   member-params=[t],
+   member-type-params=[T]
+  */
+  @patch
+  static T genericStaticMethod<T>(T t) => t;
+
+  /*member: Extension|get#instanceProperty:
+   builder-name=instanceProperty,
+   builder-params=[#this],
+   member-name=Extension|get#instanceProperty,
+   member-params=[#this]
+  */
+  @patch
+  int get instanceProperty => 123;
+
+  /*member: Extension|set#instanceProperty:
+   builder-name=instanceProperty,
+   builder-params=[#this,value],
+   member-name=Extension|set#instanceProperty,
+   member-params=[#this,value]
+  */
+  @patch
+  void set instanceProperty(int value) {}
+
+  /*member: Extension|staticProperty:
+   builder-name=staticProperty,
+   member-name=Extension|staticProperty
+  */
+  @patch
+  static int get staticProperty => 237;
+
+  /*member: Extension|staticProperty=:
+   builder-name=staticProperty,
+   builder-params=[value],
+   member-name=Extension|staticProperty=,
+   member-params=[value]
+  */
+  @patch
+  static void set staticProperty(int value) {}
+}
+
+
+@patch
+extension GenericExtension<T> on T {
+  /*member: GenericExtension|instanceMethod:
+   builder-name=instanceMethod,
+   builder-params=[#this],
+   builder-type-params=[T],
+   member-name=GenericExtension|instanceMethod,
+   member-params=[#this],
+   member-type-params=[T]
+  */
+  @patch
+  int instanceMethod() => 42;
+
+  /*member: GenericExtension|genericInstanceMethod:
+   builder-name=genericInstanceMethod,
+   builder-params=[#this,t],
+   builder-type-params=[T,T],
+   member-name=GenericExtension|genericInstanceMethod,
+   member-params=[#this,t],
+   member-type-params=[#T,T]
+  */
+  @patch
+  T genericInstanceMethod<T>(T t) => t;
+
+  /*member: GenericExtension|staticMethod:
+   builder-name=staticMethod,
+   member-name=GenericExtension|staticMethod
+  */
+  @patch
+  static int staticMethod() => 87;
+
+  /*member: GenericExtension|genericStaticMethod:
+   builder-name=genericStaticMethod,
+   builder-params=[t],
+   builder-type-params=[T],
+   member-name=GenericExtension|genericStaticMethod,
+   member-params=[t],
+   member-type-params=[T]
+  */
+  @patch
+  static T genericStaticMethod<T>(T t) => t;
+
+  /*member: GenericExtension|get#instanceProperty:
+   builder-name=instanceProperty,
+   builder-params=[#this],
+   builder-type-params=[T],
+   member-name=GenericExtension|get#instanceProperty,
+   member-params=[#this],
+   member-type-params=[T]
+  */
+  @patch
+  int get instanceProperty => 123;
+
+  /*member: GenericExtension|set#instanceProperty:
+   builder-name=instanceProperty,
+   builder-params=[#this,value],
+   builder-type-params=[T],
+   member-name=GenericExtension|set#instanceProperty,
+   member-params=[#this,value],
+   member-type-params=[T]
+  */
+  @patch
+  void set instanceProperty(int value) {}
+
+  /*member: GenericExtension|staticProperty:
+   builder-name=staticProperty,
+   member-name=GenericExtension|staticProperty
+  */
+  @patch
+  static int get staticProperty => 237;
+
+  /*member: GenericExtension|staticProperty=:
+   builder-name=staticProperty,
+   builder-params=[value],
+   member-name=GenericExtension|staticProperty=,
+   member-params=[value]
+  */
+  @patch
+  static void set staticProperty(int value) {}
+}
\ No newline at end of file
diff --git a/pkg/front_end/test/extensions/extensions_test.dart b/pkg/front_end/test/extensions/extensions_test.dart
index 33e8fb4..880d249 100644
--- a/pkg/front_end/test/extensions/extensions_test.dart
+++ b/pkg/front_end/test/extensions/extensions_test.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io' show Directory, Platform;
+import 'package:front_end/src/api_prototype/experimental_flags.dart'
+    show ExperimentalFlag;
 import 'package:front_end/src/fasta/builder/builder.dart';
 import 'package:front_end/src/fasta/builder/extension_builder.dart';
 import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
@@ -22,8 +24,11 @@
       supportedMarkers: sharedMarkers,
       createUriForFileName: createUriForFileName,
       onFailure: onFailure,
-      runTest: runTestFor(
-          const ExtensionsDataComputer(), [cfeExtensionMethodsConfig]));
+      runTest: runTestFor(const ExtensionsDataComputer(), [
+        new TestConfig(cfeMarker, 'cfe with extension methods',
+            experimentalFlags: const {ExperimentalFlag.extensionMethods: true},
+            librariesSpecificationUri: createUriForFileName('libraries.json'))
+      ]));
 }
 
 class ExtensionsDataComputer extends DataComputer<Features> {
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 1908a65..c92c98e 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
@@ -8,6 +8,7 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/testing/mock_sdk_component.dart';
+import 'package:kernel/type_environment.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -691,13 +692,17 @@
   void test_unknown_at_bottom() {
     var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
     var env = _makeEnv();
-    expect(env.isSubtypeOf(unknownType, A), isTrue);
+    expect(
+        env.isSubtypeOf(unknownType, A, SubtypeCheckMode.ignoringNullabilities),
+        isTrue);
   }
 
   void test_unknown_at_top() {
     var A = coreTypes.rawType(_addClass(_class('A')), Nullability.legacy);
     var env = _makeEnv();
-    expect(env.isSubtypeOf(A, unknownType), isTrue);
+    expect(
+        env.isSubtypeOf(A, unknownType, SubtypeCheckMode.ignoringNullabilities),
+        isTrue);
   }
 
   Class _addClass(Class c) {
diff --git a/pkg/front_end/test/fasta/types/fasta_types_test.dart b/pkg/front_end/test/fasta/types/fasta_types_test.dart
index f4dc886..5d3659a 100644
--- a/pkg/front_end/test/fasta/types/fasta_types_test.dart
+++ b/pkg/front_end/test/fasta/types/fasta_types_test.dart
@@ -26,6 +26,7 @@
     show ClassHierarchyBuilder, ClassBuilder;
 
 import "package:front_end/src/fasta/ticker.dart" show Ticker;
+import 'package:kernel/type_environment.dart';
 
 import "kernel_type_parser.dart" show KernelEnvironment, KernelFromParsedType;
 
@@ -73,7 +74,8 @@
   }
 
   bool isSubtypeImpl(DartType subtype, DartType supertype) {
-    return hierarchy.types.isSubtypeOfKernel(subtype, supertype);
+    return hierarchy.types.isSubtypeOfKernel(
+        subtype, supertype, SubtypeCheckMode.ignoringNullabilities);
   }
 
   KernelEnvironment extend(String typeParameters) {
diff --git a/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart b/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
index c8af98e..d03b95d 100644
--- a/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
+++ b/pkg/front_end/test/fasta/types/kernel_type_parser_test.dart
@@ -12,7 +12,8 @@
 
 import "package:kernel/text/ast_to_text.dart" show Printer;
 
-import "package:kernel/type_environment.dart" show TypeEnvironment;
+import "package:kernel/type_environment.dart"
+    show SubtypeCheckMode, TypeEnvironment;
 
 import "kernel_type_parser.dart"
     show KernelEnvironment, KernelFromParsedType, parseLibrary;
@@ -42,7 +43,7 @@
 
 typedef Typedef<T extends self::Object* = dynamic> = <S extends self::Object* = dynamic>(T*) →* S*;
 typedef VoidFunction = () →* void;
-typedef TestDefaultTypes = () →* self::DefaultTypes<dynamic, self::Object, self::List<dynamic>*, self::List<self::Object>*, self::Comparable<dynamic>*, (<BottomType>) →* void, () →* self::Comparable<dynamic>*>;
+typedef TestDefaultTypes = () →* self::DefaultTypes<dynamic, self::Object, self::List<dynamic>, self::List<self::Object>, self::Comparable<dynamic>, (<BottomType>) → void, () → self::Comparable<dynamic>>;
 typedef Id<T extends self::Object* = dynamic> = T*;
 typedef TestSorting = ({a: self::int, b: self::int, c: self::int}) →* void;
 class Object {
@@ -71,13 +72,13 @@
 }
 class bool extends self::Object {
 }
-class DefaultTypes<S extends self::Object* = dynamic, T extends self::Object = self::Object, U extends self::List<self::DefaultTypes::S*> = self::List<dynamic>*, V extends self::List<self::DefaultTypes::T> = self::List<self::Object>*, W extends self::Comparable<self::DefaultTypes::W> = self::Comparable<dynamic>*, X extends (self::DefaultTypes::W) → void = (<BottomType>) →* void, Y extends () → self::DefaultTypes::W = () →* self::Comparable<dynamic>*> extends self::Object {
+class DefaultTypes<S extends self::Object* = dynamic, T extends self::Object = self::Object, U extends self::List<self::DefaultTypes::S*> = self::List<dynamic>, V extends self::List<self::DefaultTypes::T> = self::List<self::Object>, W extends self::Comparable<self::DefaultTypes::W> = self::Comparable<dynamic>, X extends (self::DefaultTypes::W) → void = (<BottomType>) → void, Y extends () → self::DefaultTypes::W = () → self::Comparable<dynamic>> extends self::Object {
 }
 class Super extends self::Object implements self::Comparable<self::Sub> {
 }
 class Sub extends self::Super {
 }
-class FBound<T extends self::FBound<self::FBound::T> = self::FBound<dynamic>*> extends self::Object {
+class FBound<T extends self::FBound<self::FBound::T> = self::FBound<dynamic>> extends self::Object {
 }
 class MixinApplication = self::Object with self::FBound<self::MixinApplication> {
 }
@@ -119,8 +120,8 @@
   }
 
   bool isSubtypeImpl(DartType subtype, DartType supertype) {
-    return new TypeEnvironment(coreTypes, hierarchy)
-        .isSubtypeOf(subtype, supertype);
+    return new TypeEnvironment(coreTypes, hierarchy).isSubtypeOf(
+        subtype, supertype, SubtypeCheckMode.ignoringNullabilities);
   }
 
   KernelEnvironment extend(String typeParameters) {
diff --git a/pkg/front_end/test/fasta/types/subtypes_benchmark.dart b/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
index dc3e3f8..c46d75a 100644
--- a/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
+++ b/pkg/front_end/test/fasta/types/subtypes_benchmark.dart
@@ -14,7 +14,8 @@
 
 import "package:kernel/target/targets.dart" show NoneTarget, TargetFlags;
 
-import "package:kernel/type_environment.dart" show TypeEnvironment;
+import "package:kernel/type_environment.dart"
+    show SubtypeCheckMode, TypeEnvironment;
 
 import "kernel_type_parser.dart"
     show KernelEnvironment, KernelFromParsedType, parseLibrary;
@@ -101,7 +102,8 @@
 void performChecks(List<SubtypeCheck> checks, TypeEnvironment environment) {
   for (int i = 0; i < checks.length; i++) {
     SubtypeCheck check = checks[i];
-    bool isSubtype = environment.isSubtypeOf(check.s, check.t);
+    bool isSubtype = environment.isSubtypeOf(
+        check.s, check.t, SubtypeCheckMode.ignoringNullabilities);
     if (isSubtype != check.isSubtype) {
       throw "Check failed: $check";
     }
@@ -112,7 +114,8 @@
     List<SubtypeCheck> checks, ClassHierarchyBuilder hierarchy) {
   for (int i = 0; i < checks.length; i++) {
     SubtypeCheck check = checks[i];
-    bool isSubtype = hierarchy.types.isSubtypeOfKernel(check.s, check.t);
+    bool isSubtype = hierarchy.types.isSubtypeOfKernel(
+        check.s, check.t, SubtypeCheckMode.ignoringNullabilities);
     if (isSubtype != check.isSubtype) {
       throw "Check failed: $check";
     }
diff --git a/pkg/front_end/test/id_testing/id_testing_test.dart b/pkg/front_end/test/id_testing/id_testing_test.dart
index 07d99ba..92a4fb5 100644
--- a/pkg/front_end/test/id_testing/id_testing_test.dart
+++ b/pkg/front_end/test/id_testing/id_testing_test.dart
@@ -58,7 +58,7 @@
       Library library, Map<Id, ActualData<String>> actualMap,
       {bool verbose}) {
     new IdTestingDataExtractor(compilerResult, actualMap)
-        .computeForLibrary(library, useFileUri: true);
+        .computeForLibrary(library);
   }
 
   @override
diff --git a/pkg/front_end/test/language_versioning/language_versioning_test.dart b/pkg/front_end/test/language_versioning/language_versioning_test.dart
index 691df94..a387f9a 100644
--- a/pkg/front_end/test/language_versioning/language_versioning_test.dart
+++ b/pkg/front_end/test/language_versioning/language_versioning_test.dart
@@ -52,7 +52,7 @@
       Library library, Map<Id, ActualData<String>> actualMap,
       {bool verbose}) {
     new LanguageVersioningDataExtractor(compilerResult, actualMap)
-        .computeForLibrary(library, useFileUri: true);
+        .computeForLibrary(library);
   }
 
   @override
diff --git a/pkg/front_end/test/parser_test.dart b/pkg/front_end/test/parser_test.dart
index 3c6cffb..9daee4d 100644
--- a/pkg/front_end/test/parser_test.dart
+++ b/pkg/front_end/test/parser_test.dart
@@ -31,6 +31,8 @@
 
 import 'parser_test_listener.dart' show ParserTestListener;
 
+import 'parser_test_parser.dart' show TestParser;
+
 const String EXPECTATIONS = '''
 [
   {
@@ -58,17 +60,18 @@
   Context(this.updateExpectations);
 
   final List<Step> steps = const <Step>[
-    const ParserStep(),
+    const ListenerStep(),
+    const IntertwinedStep(),
   ];
 
   final ExpectationSet expectationSet =
       new ExpectationSet.fromJsonList(jsonDecode(EXPECTATIONS));
 }
 
-class ParserStep extends Step<TestDescription, TestDescription, Context> {
-  const ParserStep();
+class ListenerStep extends Step<TestDescription, TestDescription, Context> {
+  const ListenerStep();
 
-  String get name => "parser";
+  String get name => "listener";
 
   Future<Result<TestDescription>> run(
       TestDescription description, Context context) async {
@@ -94,3 +97,43 @@
         ".expect", "${parserTestListener.sb}", description.uri, description);
   }
 }
+
+class IntertwinedStep extends Step<TestDescription, TestDescription, Context> {
+  const IntertwinedStep();
+
+  String get name => "intertwined";
+
+  Future<Result<TestDescription>> run(
+      TestDescription description, Context context) async {
+    File f = new File.fromUri(description.uri);
+    List<int> rawBytes = f.readAsBytesSync();
+
+    Uint8List bytes = new Uint8List(rawBytes.length + 1);
+    bytes.setRange(0, rawBytes.length, rawBytes);
+
+    Utf8BytesScanner scanner =
+        new Utf8BytesScanner(bytes, includeComments: true);
+    Token firstToken = scanner.tokenize();
+
+    if (firstToken == null) {
+      return crash(description, StackTrace.current);
+    }
+
+    ParserTestListener2 parserTestListener = new ParserTestListener2();
+    TestParser parser = new TestParser(parserTestListener);
+    parserTestListener.parser = parser;
+    parser.sb = parserTestListener.sb;
+    parser.parseUnit(firstToken);
+
+    return context.match<TestDescription>(
+        ".intertwined.expect", "${parser.sb}", description.uri, description);
+  }
+}
+
+class ParserTestListener2 extends ParserTestListener {
+  TestParser parser;
+
+  void doPrint(String s) {
+    sb.writeln(("  " * parser.indent) + "listener: " + s);
+  }
+}
diff --git a/pkg/front_end/test/parser_test_listener_creator.dart b/pkg/front_end/test/parser_test_listener_creator.dart
index 1d625bf..35851e7 100644
--- a/pkg/front_end/test/parser_test_listener_creator.dart
+++ b/pkg/front_end/test/parser_test_listener_creator.dart
@@ -11,8 +11,17 @@
 import 'package:front_end/src/fasta/parser/member_kind.dart';
 import 'package:front_end/src/fasta/scanner/utf8_bytes_scanner.dart';
 import 'package:front_end/src/scanner/token.dart';
+import 'package:dart_style/dart_style.dart' show DartFormatter;
 
-main() {
+StringSink out;
+
+main(List<String> args) {
+  if (args.contains("--stdout")) {
+    out = stdout;
+  } else {
+    out = new StringBuffer();
+  }
+
   File f = new File.fromUri(
       Platform.script.resolve("../lib/src/fasta/parser/listener.dart"));
   List<int> rawBytes = f.readAsBytesSync();
@@ -23,7 +32,7 @@
   Utf8BytesScanner scanner = new Utf8BytesScanner(bytes, includeComments: true);
   Token firstToken = scanner.tokenize();
 
-  print("""
+  out.write("""
 // Copyright (c) 2019, 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.
@@ -47,15 +56,17 @@
   void doPrint(String s) {
     sb.writeln(("  " * indent) + s);
   }
-  """);
+""");
 
   ParserCreatorListener listener = new ParserCreatorListener();
   ClassMemberParser parser = new ClassMemberParser(listener);
   parser.parseUnit(firstToken);
 
-  print("""
+  out.writeln("}");
+
+  if (out is StringBuffer) {
+    stdout.write(new DartFormatter().format("$out"));
   }
-  """);
 }
 
 class ParserCreatorListener extends Listener {
@@ -79,13 +90,14 @@
   void endClassMethod(Token getOrSet, Token beginToken, Token beginParam,
       Token beginInitializers, Token endToken) {
     if (insideListenerClass) {
+      out.write("  ");
       Token token = beginToken;
       Token latestToken;
       while (true) {
         if (latestToken != null && latestToken.charEnd < token.charOffset) {
-          stdout.write(" ");
+          out.write(" ");
         }
-        stdout.write(token.lexeme);
+        out.write(token.lexeme);
         if ((token is BeginToken &&
                 token.type == TokenType.OPEN_CURLY_BRACKET) ||
             token is SimpleToken && token.type == TokenType.FUNCTION) {
@@ -99,29 +111,29 @@
       }
 
       if (token is SimpleToken && token.type == TokenType.FUNCTION) {
-        stdout.write(" null;");
+        out.write(" null;");
       } else {
-        stdout.write("\n");
+        out.write("\n    ");
         if (currentMethodName.startsWith("end")) {
-          stdout.write("indent--;\n");
+          out.write("indent--;\n    ");
         }
-        stdout.write("doPrint('$currentMethodName(");
+        out.write("doPrint('$currentMethodName(");
         String separator = "";
         for (int i = 0; i < parameters.length; i++) {
-          stdout.write(separator);
-          stdout.write(r"''$");
-          stdout.write(parameters[i]);
+          out.write(separator);
+          out.write(r"' '$");
+          out.write(parameters[i]);
           separator = ", ";
         }
-        stdout.write(")');\n");
+        out.write(")');\n  ");
 
         if (currentMethodName.startsWith("begin")) {
-          stdout.write("indent++;\n");
+          out.write("  indent++;\n  ");
         }
 
-        stdout.write("}");
+        out.write("}");
       }
-      stdout.write("\n\n");
+      out.write("\n\n");
     }
     parameters.clear();
     currentMethodName = null;